@hero-design/rn-work-uikit 1.3.0 → 1.4.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 (49) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/lib/index.js +48742 -29649
  3. package/package.json +5 -4
  4. package/src/__tests__/index-export.spec.ts +64 -0
  5. package/src/components/DatePicker/__tests__/__snapshots__/index.spec.tsx.snap +1602 -0
  6. package/src/components/DatePicker/__tests__/index.spec.tsx +56 -0
  7. package/src/components/DatePicker/index.tsx +12 -0
  8. package/src/components/FormGroup/__tests__/__snapshots__/index.spec.tsx.snap +880 -0
  9. package/src/components/FormGroup/__tests__/index.spec.tsx +179 -0
  10. package/src/components/FormGroup/__tests__/utils.spec.ts +73 -0
  11. package/src/components/FormGroup/index.tsx +97 -0
  12. package/src/components/FormGroup/utils.ts +67 -0
  13. package/src/components/RichTextEditor/EditorEvent.ts +7 -0
  14. package/src/components/RichTextEditor/EditorToolbar.tsx +216 -0
  15. package/src/components/RichTextEditor/MentionList.tsx +99 -0
  16. package/src/components/RichTextEditor/RichTextEditor.tsx +88 -0
  17. package/src/components/RichTextEditor/RichTextEditorInput.tsx +286 -0
  18. package/src/components/RichTextEditor/StyledRichTextEditor.tsx +18 -0
  19. package/src/components/RichTextEditor/StyledToolbar.ts +32 -0
  20. package/src/components/RichTextEditor/__mocks__/hero-editor.js +3 -0
  21. package/src/components/RichTextEditor/__mocks__/heroEditorApp.ts +2 -0
  22. package/src/components/RichTextEditor/__tests__/EditorToolbar.spec.tsx +144 -0
  23. package/src/components/RichTextEditor/__tests__/MentionList.spec.tsx +105 -0
  24. package/src/components/RichTextEditor/__tests__/RichTextEditorInput.spec.tsx +136 -0
  25. package/src/components/RichTextEditor/__tests__/__snapshots__/EditorToolbar.spec.tsx.snap +414 -0
  26. package/src/components/RichTextEditor/__tests__/__snapshots__/MentionList.spec.tsx.snap +13 -0
  27. package/src/components/RichTextEditor/constants.ts +9 -0
  28. package/src/{hero-editor.d.ts → components/RichTextEditor/hero-editor.d.ts} +6 -0
  29. package/src/components/RichTextEditor/heroEditorApp.ts +3 -0
  30. package/src/components/RichTextEditor/index.tsx +20 -0
  31. package/src/components/RichTextEditor/types.ts +87 -0
  32. package/src/components/RichTextEditor/utils/events.ts +31 -0
  33. package/src/components/RichTextEditor/utils/rnWebView.tsx +30 -0
  34. package/src/components/Select/__tests__/__snapshots__/index.spec.tsx.snap +1293 -0
  35. package/src/components/Select/__tests__/index.spec.tsx +43 -0
  36. package/src/components/TextInput/Group/__tests__/__snapshots__/index.spec.tsx.snap +0 -3
  37. package/src/components/TextInput/InputComponent.tsx +59 -18
  38. package/src/components/TextInput/InputRow.tsx +13 -7
  39. package/src/components/TextInput/StyledTextInput.tsx +0 -1
  40. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +0 -17
  41. package/src/components/TextInput/index.tsx +20 -11
  42. package/src/components/TextInput/types.ts +29 -4
  43. package/src/components/TimePicker/__tests__/index.spec.tsx +34 -0
  44. package/src/components/TimePicker/index.tsx +12 -0
  45. package/src/index.ts +4 -1
  46. package/src/utils/functions.ts +2 -0
  47. package/stats/1.3.0/rn-work-uikit-stats.html +1 -1
  48. package/stats/1.4.0/rn-work-uikit-stats.html +4844 -0
  49. package/src/__tests__/theme-export-override.spec.ts +0 -96
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import Select from '..';
3
+ import renderWithTheme from '../../../../testUtils/renderWithTheme';
4
+ import { noop } from '../../../utils/functions';
5
+
6
+ const options = [
7
+ { text: 'Monday', value: 'mon' },
8
+ { text: 'Tuesday', value: 'tue' },
9
+ { text: 'Wednesday', value: 'wed' },
10
+ { text: 'Thursday', value: 'thu' },
11
+ { text: 'Friday', value: 'fri' },
12
+ { text: 'Saturday', value: 'sat' },
13
+ { text: 'Sunday', value: 'sun', disabled: true },
14
+ ];
15
+
16
+ describe('Select', () => {
17
+ it('renders correctly (snapshot)', () => {
18
+ const { toJSON } = renderWithTheme(
19
+ <Select
20
+ value="mon"
21
+ onConfirm={noop}
22
+ options={options}
23
+ label="Select Label"
24
+ />
25
+ );
26
+ expect(toJSON()).toMatchSnapshot();
27
+ });
28
+ });
29
+
30
+ describe('MultiSelect', () => {
31
+ it('renders correctly (snapshot)', () => {
32
+ const { toJSON } = renderWithTheme(
33
+ <Select.Multi
34
+ value={['tue', 'wed']}
35
+ onConfirm={noop}
36
+ options={options}
37
+ label="Select Label"
38
+ footerLabel="Confirm"
39
+ />
40
+ );
41
+ expect(toJSON()).toMatchSnapshot();
42
+ });
43
+ });
@@ -91,7 +91,6 @@ exports[`TextInputGroup should render: xxx 1`] = `
91
91
  {
92
92
  "alignItems": "center",
93
93
  "backgroundColor": "transparent",
94
- "flex": 1,
95
94
  "flexDirection": "row",
96
95
  },
97
96
  ],
@@ -344,7 +343,6 @@ exports[`TextInputGroup should render: xxx 1`] = `
344
343
  {
345
344
  "alignItems": "center",
346
345
  "backgroundColor": "transparent",
347
- "flex": 1,
348
346
  "flexDirection": "row",
349
347
  },
350
348
  ],
@@ -706,7 +704,6 @@ exports[`TextInputGroup should render: xxx 1`] = `
706
704
  {
707
705
  "alignItems": "center",
708
706
  "backgroundColor": "transparent",
709
- "flex": 1,
710
707
  "flexDirection": "row",
711
708
  },
712
709
  ],
@@ -1,9 +1,52 @@
1
- import React from 'react';
2
- import { TextInput as RNTextInput } from 'react-native';
3
- import type { TextInputProps as NativeTextInputProps } from 'react-native';
1
+ import React, { useImperativeHandle, useRef } from 'react';
2
+ import {
3
+ TextInput as RNTextInput,
4
+ TextInputProps as RNTextInputProps,
5
+ } from 'react-native';
4
6
  import { StyledTextInput } from './StyledTextInput';
5
7
  import { useTheme } from '../../theme';
6
- import type { TextInputVariant } from './types';
8
+ import type {
9
+ NativeTextInputProps,
10
+ TextInputRef,
11
+ TextInputVariant,
12
+ } from './types';
13
+
14
+ interface DefaultTextInputProps {
15
+ variant: TextInputVariant;
16
+ /** Native TextInput props */
17
+ nativeInputProps: NativeTextInputProps;
18
+ }
19
+
20
+ const DefaultTextInput = React.forwardRef<TextInputRef, DefaultTextInputProps>(
21
+ ({ variant, nativeInputProps }, ref) => {
22
+ const theme = useTheme();
23
+ const inputRef = useRef<RNTextInput>(null);
24
+ useImperativeHandle(
25
+ ref,
26
+ () => ({
27
+ focus: () => inputRef.current?.focus(),
28
+ blur: () => inputRef.current?.blur(),
29
+ clear: () => inputRef.current?.clear(),
30
+ isFocused: () => inputRef.current?.isFocused() ?? false,
31
+ setNativeProps: (props: RNTextInputProps) => {
32
+ inputRef.current?.setNativeProps(props);
33
+ },
34
+ }),
35
+ []
36
+ );
37
+
38
+ // Default styled input with theme and variant support
39
+ return (
40
+ <StyledTextInput
41
+ {...nativeInputProps}
42
+ themeVariant={variant}
43
+ multiline={variant === 'textarea' || nativeInputProps.multiline}
44
+ ref={inputRef}
45
+ placeholderTextColor={theme.__hd__.textInput.colors.placeholder}
46
+ />
47
+ );
48
+ }
49
+ );
7
50
 
8
51
  export interface InputComponentProps {
9
52
  /** Input type ('text' or 'textarea') */
@@ -11,7 +54,10 @@ export interface InputComponentProps {
11
54
  /** All props passed to the underlying TextInput */
12
55
  nativeInputProps: NativeTextInputProps;
13
56
  /** Optional custom input renderer function */
14
- renderInputValue?: (inputProps: NativeTextInputProps) => React.ReactNode;
57
+ renderInputValue?: (
58
+ inputProps: NativeTextInputProps,
59
+ ref?: React.ForwardedRef<TextInputRef>
60
+ ) => React.ReactNode;
15
61
  }
16
62
 
17
63
  /**
@@ -36,21 +82,16 @@ export interface InputComponentProps {
36
82
  *
37
83
  * @param props - The component props (see InputComponentProps interface for details)
38
84
  */
39
- const InputComponent = React.forwardRef<RNTextInput, InputComponentProps>(
85
+ const InputComponent = React.forwardRef<TextInputRef, InputComponentProps>(
40
86
  ({ variant, nativeInputProps, renderInputValue }, ref) => {
41
- const theme = useTheme();
42
-
43
- return renderInputValue ? (
44
- // Custom input renderer provided
45
- <>{renderInputValue(nativeInputProps)}</>
46
- ) : (
47
- // Default styled input with theme and variant support
48
- <StyledTextInput
49
- {...nativeInputProps}
50
- themeVariant={variant}
51
- multiline={variant === 'textarea' || nativeInputProps.multiline}
87
+ if (renderInputValue) {
88
+ return <>{renderInputValue({ ...nativeInputProps }, ref)}</>;
89
+ }
90
+ return (
91
+ <DefaultTextInput
92
+ variant={variant}
93
+ nativeInputProps={nativeInputProps}
52
94
  ref={ref}
53
- placeholderTextColor={theme.__hd__.textInput.colors.placeholder}
54
95
  />
55
96
  );
56
97
  }
@@ -1,8 +1,7 @@
1
1
  import React, { useCallback, useState } from 'react';
2
- import { TextInput as RNTextInput, View } from 'react-native';
2
+ import { View } from 'react-native';
3
3
  import type {
4
4
  NativeSyntheticEvent,
5
- TextInputProps as NativeTextInputProps,
6
5
  TextInputFocusEventData,
7
6
  } from 'react-native';
8
7
  import { IconName } from '@hero-design/rn';
@@ -10,7 +9,11 @@ import { StyledInputRow } from './StyledTextInput';
10
9
  import PrefixComponent from './PrefixComponent';
11
10
  import InputComponent from './InputComponent';
12
11
  import type { State } from './StyledTextInput';
13
- import type { TextInputVariant } from './types';
12
+ import type {
13
+ NativeTextInputProps,
14
+ TextInputRef,
15
+ TextInputVariant,
16
+ } from './types';
14
17
 
15
18
  interface InputRowProps {
16
19
  /** Current state of the input (focused, error, disabled, etc.) */
@@ -22,7 +25,10 @@ interface InputRowProps {
22
25
  /** Native TextInput props passed to the input component */
23
26
  nativeInputProps: NativeTextInputProps;
24
27
  /** Optional custom render function for input value */
25
- renderInputValue?: (inputProps: NativeTextInputProps) => React.ReactNode;
28
+ renderInputValue?: (
29
+ inputProps: NativeTextInputProps,
30
+ ref?: React.ForwardedRef<TextInputRef>
31
+ ) => React.ReactNode;
26
32
  /** Whether the input value is empty */
27
33
  isEmptyValue: boolean;
28
34
  /** Whether the input should be visible when not focused and empty. Defaults to true. */
@@ -52,7 +58,7 @@ interface InputRowProps {
52
58
  * 1. Conditionally visible prefix component (icon or custom element)
53
59
  * 2. Conditionally visible input component (TextInput or custom rendered input)
54
60
  */
55
- const InputRow = React.forwardRef<RNTextInput, InputRowProps>(
61
+ const InputRow = React.forwardRef<TextInputRef, InputRowProps>(
56
62
  (
57
63
  {
58
64
  state,
@@ -75,7 +81,7 @@ const InputRow = React.forwardRef<RNTextInput, InputRowProps>(
75
81
 
76
82
  // Simplified callback functions (removed unnecessary memoization for simple cases)
77
83
  const handleFocus = useCallback(
78
- (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
84
+ (event?: NativeSyntheticEvent<TextInputFocusEventData>) => {
79
85
  setIsFocused(true);
80
86
  nativeInputProps.onFocus?.(event);
81
87
  },
@@ -83,7 +89,7 @@ const InputRow = React.forwardRef<RNTextInput, InputRowProps>(
83
89
  );
84
90
 
85
91
  const handleBlur = useCallback(
86
- (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
92
+ (event?: NativeSyntheticEvent<TextInputFocusEventData>) => {
87
93
  setIsFocused(false);
88
94
  nativeInputProps.onBlur?.(event);
89
95
  },
@@ -42,7 +42,6 @@ const StyledFloatingLabelContainer = styled(Animated.View)<{
42
42
  themeVariant: Variant;
43
43
  }>(({ themeVariant }) => ({
44
44
  flexDirection: 'row',
45
- flex: 1,
46
45
  alignItems: themeVariant === 'text' ? 'center' : 'flex-start',
47
46
  backgroundColor: 'transparent',
48
47
  }));
@@ -75,7 +75,6 @@ exports[`TextInput when user applies custom styling should respect user-provided
75
75
  {
76
76
  "alignItems": "center",
77
77
  "backgroundColor": "transparent",
78
- "flex": 1,
79
78
  "flexDirection": "row",
80
79
  },
81
80
  ],
@@ -432,7 +431,6 @@ exports[`TextInput when user chooses textarea variant should provide multiline t
432
431
  {
433
432
  "alignItems": "flex-start",
434
433
  "backgroundColor": "transparent",
435
- "flex": 1,
436
434
  "flexDirection": "row",
437
435
  },
438
436
  ],
@@ -712,7 +710,6 @@ exports[`TextInput when user encounters a disabled field should display content
712
710
  {
713
711
  "alignItems": "center",
714
712
  "backgroundColor": "transparent",
715
- "flex": 1,
716
713
  "flexDirection": "row",
717
714
  },
718
715
  ],
@@ -991,7 +988,6 @@ exports[`TextInput when user encounters a read-only field should display content
991
988
  {
992
989
  "alignItems": "center",
993
990
  "backgroundColor": "transparent",
994
- "flex": 1,
995
991
  "flexDirection": "row",
996
992
  },
997
993
  ],
@@ -1354,7 +1350,6 @@ exports[`TextInput when user has entered text should show the input content and
1354
1350
  {
1355
1351
  "alignItems": "center",
1356
1352
  "backgroundColor": "transparent",
1357
- "flex": 1,
1358
1353
  "flexDirection": "row",
1359
1354
  },
1360
1355
  ],
@@ -1717,7 +1712,6 @@ exports[`TextInput when user interacts with placeholder text starting from empty
1717
1712
  {
1718
1713
  "alignItems": "center",
1719
1714
  "backgroundColor": "transparent",
1720
- "flex": 1,
1721
1715
  "flexDirection": "row",
1722
1716
  },
1723
1717
  ],
@@ -2037,7 +2031,6 @@ exports[`TextInput when user needs programmatic control should provide ref metho
2037
2031
  {
2038
2032
  "alignItems": "center",
2039
2033
  "backgroundColor": "transparent",
2040
- "flex": 1,
2041
2034
  "flexDirection": "row",
2042
2035
  },
2043
2036
  ],
@@ -2316,7 +2309,6 @@ exports[`TextInput when user provides default values starting with pre-filled co
2316
2309
  {
2317
2310
  "alignItems": "center",
2318
2311
  "backgroundColor": "transparent",
2319
- "flex": 1,
2320
2312
  "flexDirection": "row",
2321
2313
  },
2322
2314
  ],
@@ -2672,7 +2664,6 @@ exports[`TextInput when user provides default values when both default and contr
2672
2664
  {
2673
2665
  "alignItems": "center",
2674
2666
  "backgroundColor": "transparent",
2675
- "flex": 1,
2676
2667
  "flexDirection": "row",
2677
2668
  },
2678
2669
  ],
@@ -3029,7 +3020,6 @@ exports[`TextInput when user sees a loading state should show loading indicator
3029
3020
  {
3030
3021
  "alignItems": "center",
3031
3022
  "backgroundColor": "transparent",
3032
- "flex": 1,
3033
3023
  "flexDirection": "row",
3034
3024
  },
3035
3025
  ],
@@ -3411,7 +3401,6 @@ exports[`TextInput when user sees a required field should indicate the field is
3411
3401
  {
3412
3402
  "alignItems": "center",
3413
3403
  "backgroundColor": "transparent",
3414
- "flex": 1,
3415
3404
  "flexDirection": "row",
3416
3405
  },
3417
3406
  ],
@@ -3744,7 +3733,6 @@ exports[`TextInput when user sees a textarea with character count should display
3744
3733
  {
3745
3734
  "alignItems": "flex-start",
3746
3735
  "backgroundColor": "transparent",
3747
- "flex": 1,
3748
3736
  "flexDirection": "row",
3749
3737
  },
3750
3738
  ],
@@ -4144,7 +4132,6 @@ exports[`TextInput when user sees a textarea with character count should hide ch
4144
4132
  {
4145
4133
  "alignItems": "flex-start",
4146
4134
  "backgroundColor": "transparent",
4147
- "flex": 1,
4148
4135
  "flexDirection": "row",
4149
4136
  },
4150
4137
  ],
@@ -4511,7 +4498,6 @@ exports[`TextInput when user sees an empty input field should display label and
4511
4498
  {
4512
4499
  "alignItems": "center",
4513
4500
  "backgroundColor": "transparent",
4514
- "flex": 1,
4515
4501
  "flexDirection": "row",
4516
4502
  },
4517
4503
  ],
@@ -4873,7 +4859,6 @@ exports[`TextInput when user sees an error state should display error message to
4873
4859
  {
4874
4860
  "alignItems": "center",
4875
4861
  "backgroundColor": "transparent",
4876
- "flex": 1,
4877
4862
  "flexDirection": "row",
4878
4863
  },
4879
4864
  ],
@@ -5251,7 +5236,6 @@ exports[`TextInput when user sees helper text should display guidance text to as
5251
5236
  {
5252
5237
  "alignItems": "center",
5253
5238
  "backgroundColor": "transparent",
5254
- "flex": 1,
5255
5239
  "flexDirection": "row",
5256
5240
  },
5257
5241
  ],
@@ -5571,7 +5555,6 @@ exports[`TextInput when user sees input with custom prefix and suffix elements s
5571
5555
  {
5572
5556
  "alignItems": "center",
5573
5557
  "backgroundColor": "transparent",
5574
- "flex": 1,
5575
5558
  "flexDirection": "row",
5576
5559
  },
5577
5560
  ],
@@ -1,11 +1,11 @@
1
1
  import React, { forwardRef, useCallback } from 'react';
2
- import { StyleSheet, TextInput as RNTextInput } from 'react-native';
2
+ import { StyleSheet } from 'react-native';
3
3
  import type {
4
- TextInputProps as NativeTextInputProps,
5
4
  StyleProp,
6
5
  ViewStyle,
7
6
  NativeSyntheticEvent,
8
7
  TextInputFocusEventData,
8
+ ColorValue,
9
9
  } from 'react-native';
10
10
  import {
11
11
  StyledInputWrapper,
@@ -23,8 +23,10 @@ import FloatingLabel from './FloatingLabel';
23
23
  import InputRow from './InputRow';
24
24
  import type {
25
25
  InternalTextInputProps,
26
+ NativeTextInputProps,
26
27
  TextInputHandles,
27
28
  TextInputProps,
29
+ TextInputRef,
28
30
  } from './types';
29
31
  import Group from './Group';
30
32
 
@@ -89,6 +91,17 @@ const extractBorderStyles = (style: StyleProp<ViewStyle>) => {
89
91
  return borderStyles;
90
92
  };
91
93
 
94
+ // Create container style without background color using a helper function
95
+ const getContainerStyle = (
96
+ style: StyleProp<ViewStyle>,
97
+ customBackgroundColor?: ColorValue
98
+ ) => {
99
+ const flattenedStyle = style ? { ...StyleSheet.flatten(style) } : {};
100
+ if (customBackgroundColor) {
101
+ delete flattenedStyle.backgroundColor;
102
+ }
103
+ return flattenedStyle;
104
+ };
92
105
  /**
93
106
  * TextInput Layout Structure:
94
107
  *
@@ -171,7 +184,7 @@ export const InternalTextInput = forwardRef<
171
184
 
172
185
  const theme = useTheme();
173
186
 
174
- const innerTextInput = React.useRef<RNTextInput | null>(null);
187
+ const innerTextInput = React.useRef<TextInputRef | null>(null);
175
188
  React.useImperativeHandle(
176
189
  ref,
177
190
  () => ({
@@ -182,7 +195,7 @@ export const InternalTextInput = forwardRef<
182
195
  },
183
196
  clear: () => innerTextInput.current?.clear(),
184
197
  setNativeProps: (args: NativeTextInputProps) =>
185
- innerTextInput.current?.setNativeProps(args),
198
+ innerTextInput.current?.setNativeProps?.(args),
186
199
  isFocused: () => innerTextInput.current?.isFocused() || false,
187
200
  blur: () => innerTextInput.current?.blur(),
188
201
  }),
@@ -198,7 +211,7 @@ export const InternalTextInput = forwardRef<
198
211
 
199
212
  // Simplified callback functions (removed unnecessary memoization for simple cases)
200
213
  const handleFocus = useCallback(
201
- (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
214
+ (event?: NativeSyntheticEvent<TextInputFocusEventData>) => {
202
215
  setIsFocused(true);
203
216
  onFocus?.(event);
204
217
  },
@@ -206,7 +219,7 @@ export const InternalTextInput = forwardRef<
206
219
  );
207
220
 
208
221
  const handleBlur = useCallback(
209
- (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
222
+ (event?: NativeSyntheticEvent<TextInputFocusEventData>) => {
210
223
  setIsFocused(false);
211
224
  onBlur?.(event);
212
225
  },
@@ -265,11 +278,7 @@ export const InternalTextInput = forwardRef<
265
278
  accessibilityLabel,
266
279
  };
267
280
 
268
- // Create container style without background color
269
- const containerStyle = style ? { ...StyleSheet.flatten(style) } : {};
270
- if (customBackgroundColor) {
271
- delete containerStyle.backgroundColor;
272
- }
281
+ const containerStyle = getContainerStyle(style, customBackgroundColor);
273
282
 
274
283
  const isDisabledOrReadonly = state === 'disabled' || state === 'readonly';
275
284
 
@@ -1,9 +1,11 @@
1
1
  import type {
2
- TextInputProps as NativeTextInputProps,
2
+ TextInputProps as RNTextInputProps,
3
3
  StyleProp,
4
4
  ViewStyle,
5
5
  TextStyle,
6
6
  TextInput as RNTextInput,
7
+ NativeSyntheticEvent,
8
+ TextInputFocusEventData,
7
9
  } from 'react-native';
8
10
  import type { IconName } from '@hero-design/rn';
9
11
 
@@ -14,7 +16,27 @@ export type TextInputHandles = Pick<
14
16
 
15
17
  export type TextInputVariant = 'text' | 'textarea';
16
18
 
17
- export interface TextInputProps extends NativeTextInputProps {
19
+ export type NativeTextInputProps = Omit<
20
+ RNTextInputProps,
21
+ 'onFocus' | 'onBlur'
22
+ > & {
23
+ onFocus?: (
24
+ event?: NativeSyntheticEvent<TextInputFocusEventData>
25
+ ) => void | undefined;
26
+ onBlur?: (
27
+ event?: NativeSyntheticEvent<TextInputFocusEventData>
28
+ ) => void | undefined;
29
+ };
30
+
31
+ export interface TextInputRef {
32
+ focus: () => void;
33
+ blur: () => void;
34
+ clear: () => void;
35
+ isFocused: () => boolean;
36
+ setNativeProps?: (props: RNTextInputProps) => void;
37
+ }
38
+
39
+ export type TextInputProps = NativeTextInputProps & {
18
40
  /**
19
41
  * Field label.
20
42
  */
@@ -83,7 +105,10 @@ export interface TextInputProps extends NativeTextInputProps {
83
105
  /**
84
106
  * Customise input value renderer
85
107
  */
86
- renderInputValue?: (inputProps: NativeTextInputProps) => React.ReactNode;
108
+ renderInputValue?: (
109
+ inputProps: NativeTextInputProps,
110
+ ref?: React.ForwardedRef<TextInputRef>
111
+ ) => React.ReactNode;
87
112
  /**
88
113
  * Component ref.
89
114
  */
@@ -92,7 +117,7 @@ export interface TextInputProps extends NativeTextInputProps {
92
117
  * Component variant.
93
118
  */
94
119
  variant?: TextInputVariant;
95
- }
120
+ };
96
121
 
97
122
  export interface InternalTextInputProps extends TextInputProps {
98
123
  /**
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { Platform } from 'react-native';
3
+ import TimePicker from '..';
4
+ import renderWithTheme from '../../../../testUtils/renderWithTheme';
5
+
6
+ describe('TimePicker', () => {
7
+ it('renders TimePickerIOS when OS is iOS', () => {
8
+ Platform.OS = 'ios';
9
+ const { getByTestId } = renderWithTheme(
10
+ <TimePicker
11
+ label="Start time"
12
+ value={new Date('December 17, 1995 03:24:00')}
13
+ confirmLabel="Confirm"
14
+ onChange={jest.fn()}
15
+ />
16
+ );
17
+
18
+ expect(getByTestId('timePickerInputIOS')).toBeDefined();
19
+ });
20
+
21
+ it('renders TimePickerAndroid when OS is android', () => {
22
+ Platform.OS = 'android';
23
+ const { getByTestId } = renderWithTheme(
24
+ <TimePicker
25
+ label="Start time"
26
+ value={new Date('December 17, 1995 03:24:00')}
27
+ confirmLabel="Confirm"
28
+ onChange={jest.fn()}
29
+ />
30
+ );
31
+
32
+ expect(getByTestId('timePickerInputAndroid')).toBeDefined();
33
+ });
34
+ });
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import {
3
+ TimePicker as InternalTimePicker,
4
+ TimePickerProps,
5
+ } from '@hero-design/rn';
6
+ import TextInput from '../TextInput';
7
+
8
+ const TimePicker = (props: TimePickerProps) => {
9
+ return <InternalTimePicker {...props} TextInputComponent={TextInput} />;
10
+ };
11
+
12
+ export default TimePicker;
package/src/index.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  // Re-export everything from @hero-design/rn except theme exports we want to override
2
2
  import TextInput from './components/TextInput';
3
3
  import Select from './components/Select';
4
+ import DatePicker from './components/DatePicker';
5
+ import TimePicker from './components/TimePicker';
6
+ import RichTextEditor from './components/RichTextEditor';
4
7
 
5
8
  export * from '@hero-design/rn';
6
9
 
@@ -15,4 +18,4 @@ export {
15
18
  } from './theme';
16
19
 
17
20
  export { default as theme } from './theme';
18
- export { TextInput, Select };
21
+ export { TextInput, Select, DatePicker, TimePicker, RichTextEditor };
@@ -0,0 +1,2 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2
+ export const noop = (): void => {};