@hero-design/rn 8.103.4 → 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 (41) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +19 -0
  3. package/es/index.js +53 -19
  4. package/lib/index.js +53 -19
  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/PinInput/__tests__/__snapshots__/index.spec.tsx.snap +5 -5
  11. package/src/components/PinInput/index.tsx +1 -1
  12. package/src/components/RichTextEditor/RichTextEditor.tsx +6 -2
  13. package/src/components/RichTextEditor/StyledRichTextEditor.ts +1 -4
  14. package/src/components/RichTextEditor/__tests__/RichTextEditor.spec.tsx +4 -2
  15. package/src/components/RichTextEditor/__tests__/__snapshots__/RichTextEditor.spec.tsx.snap +8 -5
  16. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +7 -0
  17. package/src/components/Select/MultiSelect/__tests__/index.spec.tsx +53 -0
  18. package/src/components/Select/MultiSelect/index.tsx +18 -8
  19. package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +6 -0
  20. package/src/components/Select/SingleSelect/__tests__/index.spec.tsx +50 -0
  21. package/src/components/Select/SingleSelect/index.tsx +19 -8
  22. package/src/components/Select/StyledSelect.tsx +25 -2
  23. package/src/components/Select/index.tsx +8 -2
  24. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +14 -0
  25. package/src/components/TextInput/index.tsx +35 -5
  26. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerAndroid.spec.tsx.snap +2 -0
  27. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +2 -0
  28. package/src/index.internal.ts +6 -1
  29. package/src/types.internal.ts +2 -3
  30. package/stats/8.103.4/rn-stats.html +0 -2
  31. package/stats/8.103.5/rn-stats.html +4842 -0
  32. package/stats/8.103.6/rn-stats.html +4844 -0
  33. package/types/components/RichTextEditor/StyledRichTextEditor.d.ts +0 -2
  34. package/types/components/Select/MultiSelect/index.d.ts +2 -1
  35. package/types/components/Select/SingleSelect/index.d.ts +2 -1
  36. package/types/components/Select/StyledSelect.d.ts +8 -1
  37. package/types/components/Select/index.d.ts +2 -2
  38. package/types/components/Select/index.internal.d.ts +1 -1
  39. package/types/components/TextInput/index.d.ts +14 -3
  40. package/types/index.internal.d.ts +1 -1
  41. package/types/types.internal.d.ts +2 -2
@@ -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', () => {
@@ -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]}
@@ -13,11 +13,13 @@ import {
13
13
  View,
14
14
  } from 'react-native';
15
15
  import type {
16
- TextInputProps as NativeTextInputProps,
16
+ TextInputProps as RNTextInputProps,
17
17
  StyleProp,
18
18
  ViewStyle,
19
19
  TextStyle,
20
20
  LayoutChangeEvent,
21
+ NativeSyntheticEvent,
22
+ TextInputFocusEventData,
21
23
  } from 'react-native';
22
24
  import {
23
25
  StyledTextInputContainer,
@@ -49,6 +51,23 @@ export type TextInputHandles = Pick<
49
51
 
50
52
  export type TextInputVariant = 'text' | 'textarea';
51
53
 
54
+ type NativeTextInputProps = Omit<RNTextInputProps, 'onFocus' | 'onBlur'> & {
55
+ onFocus?: (
56
+ event?: NativeSyntheticEvent<TextInputFocusEventData>
57
+ ) => void | undefined;
58
+ onBlur?: (
59
+ event?: NativeSyntheticEvent<TextInputFocusEventData>
60
+ ) => void | undefined;
61
+ };
62
+
63
+ export interface TextInputRef {
64
+ focus: () => void;
65
+ blur: () => void;
66
+ clear: () => void;
67
+ isFocused: () => boolean;
68
+ setNativeProps?: (props: RNTextInputProps) => void;
69
+ }
70
+
52
71
  export interface TextInputProps extends NativeTextInputProps {
53
72
  /**
54
73
  * Field label.
@@ -118,7 +137,10 @@ export interface TextInputProps extends NativeTextInputProps {
118
137
  /**
119
138
  * Customise input value renderer
120
139
  */
121
- renderInputValue?: (inputProps: NativeTextInputProps) => React.ReactNode;
140
+ renderInputValue?: (
141
+ inputProps: NativeTextInputProps,
142
+ ref?: React.ForwardedRef<TextInputRef>
143
+ ) => React.ReactNode;
122
144
  /**
123
145
  * Component ref.
124
146
  */
@@ -197,17 +219,25 @@ export const renderInput = ({
197
219
  variant: TextInputVariant;
198
220
  nativeInputProps: NativeTextInputProps;
199
221
  multiline?: boolean;
200
- renderInputValue?: (inputProps: NativeTextInputProps) => React.ReactNode;
222
+ renderInputValue?: (
223
+ inputProps: NativeTextInputProps,
224
+ ref?: React.Ref<TextInputRef>
225
+ ) => React.ReactNode;
201
226
  ref?: React.Ref<RNTextInput>;
202
227
  theme: Theme;
203
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
+
204
233
  return renderInputValue ? (
205
- renderInputValue(nativeInputProps)
234
+ renderInputValue(nativeInputProps, ref)
206
235
  ) : (
207
236
  <StyledTextInput
208
237
  {...nativeInputProps}
209
238
  themeVariant={variant}
210
- multiline={variant === 'textarea' || nativeInputProps.multiline}
239
+ multiline={multiline}
240
+ numberOfLines={numberOfLines}
211
241
  ref={ref}
212
242
  placeholderTextColor={theme.__hd__.textInput.colors.placeholder}
213
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]}
@@ -3,5 +3,10 @@ import DatePicker from './components/DatePicker/index.internal';
3
3
  import TimePicker from './components/TimePicker/index.internal';
4
4
 
5
5
  export * from '.';
6
+ export type {
7
+ MultiSelectProps,
8
+ SingleSelectProps,
9
+ DatePickerProps,
10
+ TimePickerProps,
11
+ } from './types.internal';
6
12
  export { Select, DatePicker, TimePicker };
7
- export type { MultiSelectProps, SingleSelectProps } from './types.internal';
@@ -1,10 +1,9 @@
1
+ import { DatePickerProps } from './components/DatePicker/index.internal';
1
2
  import type {
2
3
  SingleSelectProps,
3
4
  MultiSelectProps,
4
5
  } from './components/Select/index.internal';
5
-
6
- import type { DatePickerProps } from './components/DatePicker/index.internal';
7
- import type { TimePickerProps } from './components/TimePicker/index.internal';
6
+ import { TimePickerProps } from './components/TimePicker/index.internal';
8
7
 
9
8
  export * from './types';
10
9
 
@@ -4840,5 +4840,3 @@ var drawChart = (function (exports) {
4840
4840
  </body>
4841
4841
  </html>
4842
4842
 
4843
- ml>
4844
-