@hero-design/rn 8.24.0 → 8.25.1

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 (29) hide show
  1. package/.turbo/turbo-build.log +9 -9
  2. package/es/index.js +111 -60
  3. package/lib/index.js +110 -59
  4. package/package.json +5 -5
  5. package/src/components/Carousel/CardCarousel.tsx +23 -7
  6. package/src/components/Carousel/__tests__/CardCarousel.spec.tsx +177 -70
  7. package/src/components/Carousel/__tests__/__snapshots__/CardCarousel.spec.tsx.snap +294 -1
  8. package/src/components/Collapse/index.tsx +11 -10
  9. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.spec.tsx.snap +21 -15
  10. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerAndroid.spec.tsx.snap +7 -5
  11. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerCalendar.spec.tsx.snap +7 -5
  12. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +7 -5
  13. package/src/components/Error/StyledError.tsx +2 -0
  14. package/src/components/Error/__tests__/__snapshots__/index.spec.tsx.snap +8 -0
  15. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +28 -20
  16. package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +28 -20
  17. package/src/components/Spinner/AnimatedSpinner.tsx +2 -2
  18. package/src/components/TextInput/StyledTextInput.tsx +4 -0
  19. package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +21 -1
  20. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +112 -78
  21. package/src/components/TextInput/index.tsx +1 -4
  22. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerAndroid.spec.tsx.snap +14 -10
  23. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +14 -10
  24. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +9 -1
  25. package/src/theme/components/error.ts +6 -1
  26. package/src/theme/components/textInput.ts +16 -2
  27. package/types/components/Collapse/index.d.ts +1 -1
  28. package/types/theme/components/error.d.ts +4 -0
  29. package/types/theme/components/textInput.d.ts +4 -0
@@ -1,104 +1,211 @@
1
1
  import { waitFor } from '@testing-library/react-native';
2
2
  import React from 'react';
3
- import { FlatList } from 'react-native';
3
+ import { FlatList, Platform } from 'react-native';
4
4
  import { CardCarousel, CardCarouselHandles } from '../CardCarousel';
5
5
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
6
6
  import Typography from '../../Typography';
7
7
 
8
8
  describe('CardCarousel', () => {
9
- it('should render correctly', () => {
10
- const wrapper = renderWithTheme(
11
- <CardCarousel
12
- testID="cardCarousel"
13
- style={{ width: 100, height: 100 }}
14
- items={[
15
- <Typography.Text> screen 1</Typography.Text>,
16
- <Typography.Text> screen 2</Typography.Text>,
17
- ]}
18
- />
19
- );
20
-
21
- expect(wrapper.toJSON()).toMatchSnapshot();
22
- expect(wrapper.queryAllByText('screen 1')).toHaveLength(1);
23
- expect(wrapper.queryAllByText('screen 2')).toHaveLength(1);
24
- expect(wrapper.queryAllByTestId('pageControl')).toHaveLength(1);
25
- });
26
-
27
- describe('autoPlay', () => {
28
- it('should call scrollToIndex 1', () => {
29
- jest.useFakeTimers();
30
- const carouselRef = React.createRef<
31
- CardCarouselHandles & {
32
- getFlatListRef: () => FlatList;
33
- }
34
- >();
9
+ describe('ios', () => {
10
+ beforeAll(() => {
11
+ Platform.OS = 'ios';
12
+ });
35
13
 
36
- renderWithTheme(
14
+ it('should render correctly on iOS', () => {
15
+ const wrapper = renderWithTheme(
37
16
  <CardCarousel
38
- ref={carouselRef}
39
- autoPlay
40
- autoPlayInterval={3000}
17
+ testID="cardCarousel"
18
+ style={{ width: 100, height: 100 }}
41
19
  items={[
42
20
  <Typography.Text> screen 1</Typography.Text>,
43
21
  <Typography.Text> screen 2</Typography.Text>,
44
22
  ]}
45
23
  />
46
24
  );
47
- const flatListRef = carouselRef.current!.getFlatListRef()!;
48
- const snapToIndexSpy = jest.spyOn(flatListRef, 'scrollToIndex');
49
- jest.advanceTimersByTime(3000);
50
- expect(snapToIndexSpy).toHaveBeenCalledWith({
51
- animated: true,
52
- index: 1,
53
- viewPosition: 0.5,
25
+
26
+ expect(wrapper.toJSON()).toMatchSnapshot();
27
+ expect(wrapper.queryAllByText('screen 1')).toHaveLength(1);
28
+ expect(wrapper.queryAllByText('screen 2')).toHaveLength(1);
29
+ expect(wrapper.queryAllByTestId('pageControl')).toHaveLength(1);
30
+ });
31
+
32
+ describe('autoPlay', () => {
33
+ it('should call scrollToIndex 1', () => {
34
+ jest.useFakeTimers();
35
+ const carouselRef = React.createRef<
36
+ CardCarouselHandles & {
37
+ getFlatListRef: () => FlatList;
38
+ }
39
+ >();
40
+
41
+ renderWithTheme(
42
+ <CardCarousel
43
+ ref={carouselRef}
44
+ autoPlay
45
+ autoPlayInterval={3000}
46
+ items={[
47
+ <Typography.Text> screen 1</Typography.Text>,
48
+ <Typography.Text> screen 2</Typography.Text>,
49
+ ]}
50
+ />
51
+ );
52
+ const flatListRef = carouselRef.current!.getFlatListRef()!;
53
+ const snapToIndexSpy = jest.spyOn(flatListRef, 'scrollToIndex');
54
+ jest.advanceTimersByTime(3000);
55
+ expect(snapToIndexSpy).toHaveBeenCalledWith({
56
+ animated: true,
57
+ index: 1,
58
+ viewPosition: 0.5,
59
+ });
60
+
61
+ jest.useRealTimers();
54
62
  });
63
+ });
55
64
 
56
- jest.useRealTimers();
65
+ describe('hidePageControl', () => {
66
+ const wrapper = renderWithTheme(
67
+ <CardCarousel
68
+ style={{ width: 100, height: 100 }}
69
+ hidePageControl
70
+ items={[
71
+ <Typography.Text> screen 1</Typography.Text>,
72
+ <Typography.Text> screen 2</Typography.Text>,
73
+ ]}
74
+ />
75
+ );
76
+ expect(wrapper.queryAllByTestId('pageControl')).toHaveLength(0);
57
77
  });
58
- });
59
78
 
60
- describe('hidePageControl', () => {
61
- const wrapper = renderWithTheme(
62
- <CardCarousel
63
- style={{ width: 100, height: 100 }}
64
- hidePageControl
65
- items={[
66
- <Typography.Text> screen 1</Typography.Text>,
67
- <Typography.Text> screen 2</Typography.Text>,
68
- ]}
69
- />
70
- );
71
- expect(wrapper.queryAllByTestId('pageControl')).toHaveLength(0);
79
+ describe('snapToIndex', () => {
80
+ it('should render correctly', () => {
81
+ const carouselRef = React.createRef<
82
+ CardCarouselHandles & {
83
+ getFlatListRef: () => FlatList;
84
+ }
85
+ >();
86
+
87
+ renderWithTheme(
88
+ <CardCarousel
89
+ ref={carouselRef}
90
+ items={[
91
+ <Typography.Text> screen 1</Typography.Text>,
92
+ <Typography.Text> screen 2</Typography.Text>,
93
+ <Typography.Text> screen 3</Typography.Text>,
94
+ ]}
95
+ />
96
+ );
97
+
98
+ const flatListRef = carouselRef.current!.getFlatListRef()!;
99
+ const snapToIndexSpy = jest.spyOn(flatListRef, 'scrollToIndex');
100
+ carouselRef.current?.snapToIndex(2);
101
+ waitFor(() => expect(snapToIndexSpy).toHaveBeenCalled());
102
+
103
+ expect(snapToIndexSpy).toHaveBeenCalledWith({
104
+ animated: true,
105
+ index: 2,
106
+ viewPosition: 0.5,
107
+ });
108
+ });
109
+ });
72
110
  });
111
+ describe('android', () => {
112
+ beforeAll(() => {
113
+ Platform.OS = 'android';
114
+ });
115
+ it('should render correctly on iOS', () => {
116
+ const wrapper = renderWithTheme(
117
+ <CardCarousel
118
+ testID="cardCarousel"
119
+ style={{ width: 100, height: 100 }}
120
+ items={[
121
+ <Typography.Text> screen 1</Typography.Text>,
122
+ <Typography.Text> screen 2</Typography.Text>,
123
+ ]}
124
+ />
125
+ );
73
126
 
74
- describe('snapToIndex', () => {
75
- it('should render correctly', () => {
76
- const carouselRef = React.createRef<
77
- CardCarouselHandles & {
78
- getFlatListRef: () => FlatList;
79
- }
80
- >();
127
+ expect(wrapper.toJSON()).toMatchSnapshot();
128
+ expect(wrapper.queryAllByText('screen 1')).toHaveLength(1);
129
+ expect(wrapper.queryAllByText('screen 2')).toHaveLength(1);
130
+ expect(wrapper.queryAllByTestId('pageControl')).toHaveLength(1);
131
+ });
132
+
133
+ describe('autoPlay', () => {
134
+ it('should call scrollToIndex 1', () => {
135
+ jest.useFakeTimers();
136
+ const carouselRef = React.createRef<
137
+ CardCarouselHandles & {
138
+ getFlatListRef: () => FlatList;
139
+ }
140
+ >();
141
+
142
+ renderWithTheme(
143
+ <CardCarousel
144
+ ref={carouselRef}
145
+ autoPlay
146
+ autoPlayInterval={3000}
147
+ items={[
148
+ <Typography.Text> screen 1</Typography.Text>,
149
+ <Typography.Text> screen 2</Typography.Text>,
150
+ ]}
151
+ />
152
+ );
153
+ const flatListRef = carouselRef.current!.getFlatListRef()!;
154
+ const snapToIndexSpy = jest.spyOn(flatListRef, 'scrollToIndex');
155
+ jest.advanceTimersByTime(3000);
156
+ expect(snapToIndexSpy).toHaveBeenCalledWith({
157
+ animated: true,
158
+ index: 1,
159
+ viewPosition: undefined,
160
+ });
81
161
 
82
- renderWithTheme(
162
+ jest.useRealTimers();
163
+ });
164
+ });
165
+
166
+ describe('hidePageControl', () => {
167
+ const wrapper = renderWithTheme(
83
168
  <CardCarousel
84
- ref={carouselRef}
169
+ style={{ width: 100, height: 100 }}
170
+ hidePageControl
85
171
  items={[
86
172
  <Typography.Text> screen 1</Typography.Text>,
87
173
  <Typography.Text> screen 2</Typography.Text>,
88
- <Typography.Text> screen 3</Typography.Text>,
89
174
  ]}
90
175
  />
91
176
  );
177
+ expect(wrapper.queryAllByTestId('pageControl')).toHaveLength(0);
178
+ });
179
+
180
+ describe('snapToIndex', () => {
181
+ it('should render correctly', () => {
182
+ const carouselRef = React.createRef<
183
+ CardCarouselHandles & {
184
+ getFlatListRef: () => FlatList;
185
+ }
186
+ >();
187
+
188
+ renderWithTheme(
189
+ <CardCarousel
190
+ ref={carouselRef}
191
+ items={[
192
+ <Typography.Text> screen 1</Typography.Text>,
193
+ <Typography.Text> screen 2</Typography.Text>,
194
+ <Typography.Text> screen 3</Typography.Text>,
195
+ ]}
196
+ />
197
+ );
92
198
 
93
- const flatListRef = carouselRef.current!.getFlatListRef()!;
94
- const snapToIndexSpy = jest.spyOn(flatListRef, 'scrollToIndex');
95
- carouselRef.current?.snapToIndex(2);
96
- waitFor(() => expect(snapToIndexSpy).toHaveBeenCalled());
199
+ const flatListRef = carouselRef.current!.getFlatListRef()!;
200
+ const snapToIndexSpy = jest.spyOn(flatListRef, 'scrollToIndex');
201
+ carouselRef.current?.snapToIndex(2);
202
+ waitFor(() => expect(snapToIndexSpy).toHaveBeenCalled());
97
203
 
98
- expect(snapToIndexSpy).toHaveBeenCalledWith({
99
- animated: true,
100
- index: 2,
101
- viewPosition: 0.5,
204
+ expect(snapToIndexSpy).toHaveBeenCalledWith({
205
+ animated: true,
206
+ index: 2,
207
+ viewPosition: undefined,
208
+ });
102
209
  });
103
210
  });
104
211
  });
@@ -1,6 +1,299 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`CardCarousel should render correctly 1`] = `
3
+ exports[`CardCarousel android should render correctly on iOS 1`] = `
4
+ <View
5
+ style={
6
+ Array [
7
+ Object {},
8
+ Object {
9
+ "height": 100,
10
+ "width": 100,
11
+ },
12
+ ]
13
+ }
14
+ testID="cardCarousel"
15
+ >
16
+ <RCTScrollView
17
+ bounces={false}
18
+ contentInset={
19
+ Object {
20
+ "bottom": 0,
21
+ "left": 24,
22
+ "right": 24,
23
+ "top": 0,
24
+ }
25
+ }
26
+ data={
27
+ Array [
28
+ <Text>
29
+ screen 1
30
+ </Text>,
31
+ <Text>
32
+ screen 2
33
+ </Text>,
34
+ ]
35
+ }
36
+ decelerationRate="fast"
37
+ getItem={[Function]}
38
+ getItemCount={[Function]}
39
+ getItemLayout={[Function]}
40
+ horizontal={true}
41
+ keyExtractor={[Function]}
42
+ onContentSizeChange={[Function]}
43
+ onLayout={[Function]}
44
+ onMomentumScrollBegin={[Function]}
45
+ onMomentumScrollEnd={[Function]}
46
+ onScroll={[Function]}
47
+ onScrollBeginDrag={[Function]}
48
+ onScrollEndDrag={[Function]}
49
+ onViewableItemsChanged={[Function]}
50
+ pagingEnabled={true}
51
+ removeClippedSubviews={true}
52
+ renderItem={[Function]}
53
+ renderToHardwareTextureAndroid={true}
54
+ scrollEventThrottle={32}
55
+ showsHorizontalScrollIndicator={false}
56
+ snapToAlignment="center"
57
+ snapToInterval={0}
58
+ stickyHeaderIndices={Array []}
59
+ viewabilityConfig={
60
+ Object {
61
+ "itemVisiblePercentThreshold": 80,
62
+ }
63
+ }
64
+ viewabilityConfigCallbackPairs={
65
+ Array [
66
+ Object {
67
+ "onViewableItemsChanged": [Function],
68
+ "viewabilityConfig": Object {
69
+ "itemVisiblePercentThreshold": 80,
70
+ },
71
+ },
72
+ ]
73
+ }
74
+ >
75
+ <View>
76
+ <View
77
+ style={
78
+ Array [
79
+ Object {
80
+ "flexDirection": "row",
81
+ },
82
+ null,
83
+ ]
84
+ }
85
+ >
86
+ <View
87
+ style={
88
+ Array [
89
+ Object {
90
+ "padding": 8,
91
+ },
92
+ Object {
93
+ "width": 0,
94
+ },
95
+ ]
96
+ }
97
+ >
98
+ <View
99
+ style={
100
+ Array [
101
+ Object {
102
+ "borderRadius": 8,
103
+ "elevation": 4,
104
+ "flex": 1,
105
+ "shadowColor": "#001f23",
106
+ "shadowOffset": Object {
107
+ "height": 2,
108
+ "width": 0,
109
+ },
110
+ "shadowOpacity": 0.12,
111
+ "shadowRadius": 8,
112
+ },
113
+ undefined,
114
+ ]
115
+ }
116
+ >
117
+ <View
118
+ style={
119
+ Array [
120
+ Object {
121
+ "borderRadius": 12,
122
+ "overflow": "hidden",
123
+ },
124
+ Array [
125
+ Object {
126
+ "borderRadius": 8,
127
+ "flex": 1,
128
+ "overflow": "hidden",
129
+ },
130
+ undefined,
131
+ ],
132
+ ]
133
+ }
134
+ >
135
+ <Text
136
+ allowFontScaling={false}
137
+ style={
138
+ Array [
139
+ Object {
140
+ "color": "#001f23",
141
+ "fontFamily": "BeVietnamPro-Regular",
142
+ "fontSize": 14,
143
+ "letterSpacing": 0.42,
144
+ "lineHeight": 22,
145
+ },
146
+ undefined,
147
+ ]
148
+ }
149
+ themeFontSize="medium"
150
+ themeFontWeight="regular"
151
+ themeIntent="body"
152
+ themeTypeface="neutral"
153
+ >
154
+ screen 1
155
+ </Text>
156
+ </View>
157
+ </View>
158
+ </View>
159
+ </View>
160
+ <View
161
+ style={
162
+ Array [
163
+ Object {
164
+ "flexDirection": "row",
165
+ },
166
+ null,
167
+ ]
168
+ }
169
+ >
170
+ <View
171
+ style={
172
+ Array [
173
+ Object {
174
+ "padding": 8,
175
+ },
176
+ Object {
177
+ "width": 0,
178
+ },
179
+ ]
180
+ }
181
+ >
182
+ <View
183
+ style={
184
+ Array [
185
+ Object {
186
+ "borderRadius": 8,
187
+ "elevation": 4,
188
+ "flex": 1,
189
+ "shadowColor": "#001f23",
190
+ "shadowOffset": Object {
191
+ "height": 2,
192
+ "width": 0,
193
+ },
194
+ "shadowOpacity": 0.12,
195
+ "shadowRadius": 8,
196
+ },
197
+ undefined,
198
+ ]
199
+ }
200
+ >
201
+ <View
202
+ style={
203
+ Array [
204
+ Object {
205
+ "borderRadius": 12,
206
+ "overflow": "hidden",
207
+ },
208
+ Array [
209
+ Object {
210
+ "borderRadius": 8,
211
+ "flex": 1,
212
+ "overflow": "hidden",
213
+ },
214
+ undefined,
215
+ ],
216
+ ]
217
+ }
218
+ >
219
+ <Text
220
+ allowFontScaling={false}
221
+ style={
222
+ Array [
223
+ Object {
224
+ "color": "#001f23",
225
+ "fontFamily": "BeVietnamPro-Regular",
226
+ "fontSize": 14,
227
+ "letterSpacing": 0.42,
228
+ "lineHeight": 22,
229
+ },
230
+ undefined,
231
+ ]
232
+ }
233
+ themeFontSize="medium"
234
+ themeFontWeight="regular"
235
+ themeIntent="body"
236
+ themeTypeface="neutral"
237
+ >
238
+ screen 2
239
+ </Text>
240
+ </View>
241
+ </View>
242
+ </View>
243
+ </View>
244
+ </View>
245
+ </RCTScrollView>
246
+ <View
247
+ style={
248
+ Array [
249
+ Object {
250
+ "alignItems": "center",
251
+ "flexDirection": "row",
252
+ },
253
+ Array [
254
+ Object {
255
+ "alignSelf": "center",
256
+ "marginTop": 16,
257
+ },
258
+ undefined,
259
+ ],
260
+ ]
261
+ }
262
+ testID="pageControl"
263
+ >
264
+ <View
265
+ collapsable={false}
266
+ style={
267
+ Object {
268
+ "backgroundColor": "#401960",
269
+ "borderRadius": 999,
270
+ "height": 8,
271
+ "marginHorizontal": 8,
272
+ "opacity": 1,
273
+ "width": 24,
274
+ }
275
+ }
276
+ testID="page-control-indicator0"
277
+ />
278
+ <View
279
+ collapsable={false}
280
+ style={
281
+ Object {
282
+ "backgroundColor": "#401960",
283
+ "borderRadius": 999,
284
+ "height": 8,
285
+ "marginHorizontal": 8,
286
+ "opacity": 0.5,
287
+ "width": 8,
288
+ }
289
+ }
290
+ testID="page-control-indicator1"
291
+ />
292
+ </View>
293
+ </View>
294
+ `;
295
+
296
+ exports[`CardCarousel ios should render correctly on iOS 1`] = `
4
297
  <View
5
298
  style={
6
299
  Array [
@@ -1,13 +1,13 @@
1
- import { Animated, Easing } from 'react-native';
1
+ import type { ReactNode } from 'react';
2
2
  import React, { useCallback, useEffect } from 'react';
3
3
  import type { StyleProp, ViewProps, ViewStyle } from 'react-native';
4
- import type { ReactNode } from 'react';
4
+ import { LayoutAnimation, Platform, UIManager } from 'react-native';
5
+ import { usePrevious } from '../../utils/hooks';
5
6
  import {
6
7
  StyledChildWrapper,
7
8
  StyledHiddenWrapper,
8
9
  StyledWrapper,
9
10
  } from './StyledCollapse';
10
- import { usePrevious } from '../../utils/hooks';
11
11
 
12
12
  export interface CollapseProps extends ViewProps {
13
13
  /*
@@ -28,8 +28,13 @@ export interface CollapseProps extends ViewProps {
28
28
  testID?: string;
29
29
  }
30
30
 
31
+ if (Platform.OS === 'android') {
32
+ if (UIManager.setLayoutAnimationEnabledExperimental) {
33
+ UIManager.setLayoutAnimationEnabledExperimental(true);
34
+ }
35
+ }
36
+
31
37
  const Collapse = ({ open = false, children, testID, style }: CollapseProps) => {
32
- const collapseAnim = React.useRef(new Animated.Value(0)).current;
33
38
  const [contentHeight, setContentHeight] = React.useState<number>(0);
34
39
 
35
40
  const previousOpenState = usePrevious(open);
@@ -39,11 +44,7 @@ const Collapse = ({ open = false, children, testID, style }: CollapseProps) => {
39
44
  (open !== previousOpenState && previousOpenState !== undefined) ||
40
45
  open
41
46
  ) {
42
- Animated.timing(collapseAnim, {
43
- toValue: open ? contentHeight : 0,
44
- easing: Easing.inOut(Easing.cubic),
45
- useNativeDriver: false,
46
- }).start();
47
+ LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
47
48
  }
48
49
  }, [open, previousOpenState, contentHeight]);
49
50
 
@@ -54,7 +55,7 @@ const Collapse = ({ open = false, children, testID, style }: CollapseProps) => {
54
55
  return (
55
56
  <StyledWrapper
56
57
  style={{
57
- height: collapseAnim,
58
+ height: open ? contentHeight : 0,
58
59
  }}
59
60
  testID={testID}
60
61
  >