@hero-design/rn 8.63.4-alpha.0 → 8.64.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 (48) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +12 -0
  3. package/es/index.js +85 -38
  4. package/lib/index.js +85 -38
  5. package/package.json +1 -1
  6. package/src/components/BottomSheet/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
  7. package/src/components/BottomSheet/__tests__/index.spec.tsx +17 -0
  8. package/src/components/BottomSheet/index.tsx +6 -0
  9. package/src/components/Calendar/CalendarRowItem.tsx +3 -1
  10. package/src/components/Calendar/StyledCalendar.tsx +21 -8
  11. package/src/components/Calendar/__tests__/CalendarRowItem.spec.tsx +1 -0
  12. package/src/components/Calendar/__tests__/__snapshots__/CalendarRowItem.spec.tsx.snap +4 -2
  13. package/src/components/Calendar/__tests__/index.spec.tsx +7 -1
  14. package/src/components/Calendar/index.tsx +30 -8
  15. package/src/components/DatePicker/DatePickerCalendar.tsx +14 -10
  16. package/src/components/DatePicker/DatePickerIOS.tsx +2 -0
  17. package/src/components/DatePicker/__tests__/DatePickerCalendar.spec.tsx +37 -0
  18. package/src/components/DatePicker/__tests__/DatePickerIOS.spec.tsx +34 -0
  19. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +5 -0
  20. package/src/components/DatePicker/types.ts +4 -0
  21. package/src/components/FAB/ActionGroup/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
  22. package/src/components/FAB/ActionGroup/__tests__/index.spec.tsx +45 -24
  23. package/src/components/FAB/ActionGroup/index.tsx +6 -0
  24. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +20 -0
  25. package/src/components/Select/MultiSelect/__tests__/index.spec.tsx +28 -0
  26. package/src/components/Select/MultiSelect/index.tsx +6 -0
  27. package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +15 -0
  28. package/src/components/Select/SingleSelect/__tests__/index.spec.tsx +25 -0
  29. package/src/components/Select/SingleSelect/index.tsx +6 -0
  30. package/src/components/TimePicker/TimePickerIOS.tsx +2 -0
  31. package/src/components/TimePicker/__tests__/TimePickerIOS.spec.tsx +31 -0
  32. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +5 -0
  33. package/src/components/TimePicker/types.ts +4 -0
  34. package/src/testHelpers/utils.ts +21 -0
  35. package/stats/8.64.0/rn-stats.html +4844 -0
  36. package/stats/8.64.1/rn-stats.html +4842 -0
  37. package/types/components/BottomSheet/index.d.ts +5 -1
  38. package/types/components/Calendar/CalendarRowItem.d.ts +2 -1
  39. package/types/components/Calendar/StyledCalendar.d.ts +7 -0
  40. package/types/components/DatePicker/DatePickerCalendar.d.ts +1 -1
  41. package/types/components/DatePicker/DatePickerIOS.d.ts +1 -1
  42. package/types/components/DatePicker/types.d.ts +4 -0
  43. package/types/components/FAB/ActionGroup/index.d.ts +4 -0
  44. package/types/components/Select/MultiSelect/index.d.ts +5 -1
  45. package/types/components/Select/SingleSelect/index.d.ts +5 -1
  46. package/types/components/Select/index.d.ts +1 -1
  47. package/types/components/TimePicker/TimePickerIOS.d.ts +1 -1
  48. package/types/components/TimePicker/types.d.ts +4 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.63.4-alpha.0",
3
+ "version": "8.64.1",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -73,6 +73,11 @@ exports[`BottomSheet renders correctly with open state 1`] = `
73
73
  <Modal
74
74
  hardwareAccelerated={false}
75
75
  onRequestClose={[MockFunction]}
76
+ supportedOrientations={
77
+ [
78
+ "portrait",
79
+ ]
80
+ }
76
81
  transparent={true}
77
82
  visible={true}
78
83
  >
@@ -3,6 +3,7 @@ import React from 'react';
3
3
  import { Button, Text } from 'react-native';
4
4
  import BottomSheet from '..';
5
5
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
6
+ import { setOrientation } from '../../../testHelpers/utils';
6
7
 
7
8
  const Content = () => <Text>Content</Text>;
8
9
 
@@ -57,6 +58,22 @@ describe('BottomSheet', () => {
57
58
  expect(toJSON()).toMatchSnapshot();
58
59
  });
59
60
 
61
+ it('renders correctly in landscape mode', () => {
62
+ const { getByText } = renderWithTheme(
63
+ <BottomSheet
64
+ open
65
+ header="Title"
66
+ onRequestClose={jest.fn()}
67
+ supportedOrientations={['landscape', 'portrait']}
68
+ >
69
+ <Content />
70
+ </BottomSheet>
71
+ );
72
+ setOrientation('landscape');
73
+ expect(getByText('Title')).toBeDefined();
74
+ expect(getByText('Content')).toBeDefined();
75
+ });
76
+
60
77
  describe('Header', () => {
61
78
  it('renders default header correctly', () => {
62
79
  const { getByText } = renderWithTheme(
@@ -78,6 +78,10 @@ interface BottomSheetProps {
78
78
  * keyboardAvoidingView's props
79
79
  * */
80
80
  keyboardAvoidingViewProps?: KeyboardAvoidingViewProps;
81
+ /**
82
+ * Supported orientations for the BottomSheet modal, iOS only.
83
+ */
84
+ supportedOrientations?: ('portrait' | 'landscape')[];
81
85
  }
82
86
 
83
87
  const BottomSheet = ({
@@ -95,6 +99,7 @@ const BottomSheet = ({
95
99
  style,
96
100
  testID,
97
101
  keyboardAvoidingViewProps = {},
102
+ supportedOrientations = ['portrait'],
98
103
  }: BottomSheetProps): JSX.Element => {
99
104
  const { height } = Dimensions.get('window');
100
105
 
@@ -161,6 +166,7 @@ const BottomSheet = ({
161
166
  transparent
162
167
  testID={testID}
163
168
  onShow={onOpen}
169
+ supportedOrientations={supportedOrientations}
164
170
  >
165
171
  <StyledWrapper pointerEvents="box-none">
166
172
  <StyledKeyboardAvoidingView
@@ -20,6 +20,7 @@ export interface CalendarRowItemProps {
20
20
  isSelected?: boolean;
21
21
  textIntent?: 'body' | 'subdued';
22
22
  marked?: boolean;
23
+ itemWidth?: number;
23
24
  }
24
25
 
25
26
  const CalendarRowItem = ({
@@ -29,8 +30,9 @@ const CalendarRowItem = ({
29
30
  isSelected,
30
31
  textIntent = 'body',
31
32
  marked = false,
33
+ itemWidth,
32
34
  }: CalendarRowItemProps) => (
33
- <StyledCalendarRowItem testID="calendar-date-cell">
35
+ <StyledCalendarRowItem testID="calendar-date-cell" themeItemWidth={itemWidth}>
34
36
  <StyledCalendarCell
35
37
  variant={getCellVariant(isSelected, isCurrent)}
36
38
  onPress={onPress}
@@ -12,8 +12,12 @@ const StyledCalendarHeader = styled(View)(({ theme }) => ({
12
12
  paddingVertical: theme.__hd__.calendar.space.headerVerticalPadding,
13
13
  }));
14
14
 
15
- const StyledCalendarDayNameCell = styled(View)<ViewProps>(({ theme }) => ({
16
- width: theme.__hd__.calendar.sizes.cellWidth,
15
+ const StyledCalendarDayNameCell = styled(View)<
16
+ ViewProps & {
17
+ themeItemWidth?: number;
18
+ }
19
+ >(({ theme, themeItemWidth }) => ({
20
+ width: themeItemWidth || theme.__hd__.calendar.sizes.cellWidth,
17
21
  height: theme.__hd__.calendar.sizes.cellHeight,
18
22
  alignItems: 'center',
19
23
  justifyContent: 'center',
@@ -21,7 +25,8 @@ const StyledCalendarDayNameCell = styled(View)<ViewProps>(({ theme }) => ({
21
25
 
22
26
  const StyledCalendarCell = styled(TouchableOpacity)<{
23
27
  variant?: 'default' | 'current' | 'selected';
24
- }>(({ theme, variant = 'default' }) => ({
28
+ themeItemWidth?: number;
29
+ }>(({ theme, variant = 'default', themeItemWidth }) => ({
25
30
  borderColor: theme.__hd__.calendar.colors.border,
26
31
  borderWidth: variant === 'current' ? 1 : 0,
27
32
  borderRadius: theme.__hd__.calendar.radii.default,
@@ -29,7 +34,7 @@ const StyledCalendarCell = styled(TouchableOpacity)<{
29
34
  justifyContent: 'center',
30
35
  backgroundColor:
31
36
  variant === 'selected' ? theme.__hd__.calendar.colors.primary : undefined,
32
- width: theme.__hd__.calendar.sizes.cellCircleWidth,
37
+ width: themeItemWidth || theme.__hd__.calendar.sizes.cellCircleWidth,
33
38
  height: theme.__hd__.calendar.sizes.cellCircleHeight,
34
39
  }));
35
40
 
@@ -39,18 +44,26 @@ const StyledCalendarRow = styled(View)<ViewProps>(({ theme }) => ({
39
44
  flexWrap: 'wrap',
40
45
  }));
41
46
 
42
- const StyledCalendarRowItem = styled(View)<ViewProps>(({ theme }) => ({
47
+ const StyledCalendarRowItem = styled(View)<
48
+ ViewProps & {
49
+ themeItemWidth?: number;
50
+ }
51
+ >(({ theme, themeItemWidth }) => ({
43
52
  flexBasis: `${Math.floor(100.0 / 7.0)}%`,
44
53
  alignItems: 'center',
45
- width: theme.__hd__.calendar.sizes.cellWidth,
54
+ width: themeItemWidth || theme.__hd__.calendar.sizes.cellWidth,
46
55
  height: theme.__hd__.calendar.sizes.cellHeight,
47
56
  justifyContent: 'center',
48
57
  }));
49
58
 
50
- const StyledDisabledCalendarRowItem = styled(View)<ViewProps>(({ theme }) => ({
59
+ const StyledDisabledCalendarRowItem = styled(View)<
60
+ ViewProps & {
61
+ themeItemWidth?: number;
62
+ }
63
+ >(({ theme, themeItemWidth }) => ({
51
64
  flexBasis: `${Math.floor(100.0 / 7.0)}%`,
52
65
  alignItems: 'center',
53
- width: theme.__hd__.calendar.sizes.cellWidth,
66
+ width: themeItemWidth || theme.__hd__.calendar.sizes.cellWidth,
54
67
  height: theme.__hd__.calendar.sizes.cellHeight,
55
68
  }));
56
69
 
@@ -14,6 +14,7 @@ describe('CalendarRowItem', () => {
14
14
  onPress={jest.fn()}
15
15
  textIntent={textIntent}
16
16
  marked
17
+ itemWidth={120}
17
18
  />
18
19
  );
19
20
 
@@ -16,12 +16,13 @@ exports[`CalendarRowItem renders correctly 1`] = `
16
16
  "flexBasis": "14%",
17
17
  "height": 48,
18
18
  "justifyContent": "center",
19
- "width": 48,
19
+ "width": 120,
20
20
  },
21
21
  undefined,
22
22
  ]
23
23
  }
24
24
  testID="calendar-date-cell"
25
+ themeItemWidth={120}
25
26
  >
26
27
  <View
27
28
  accessibilityState={
@@ -143,12 +144,13 @@ exports[`CalendarRowItem renders correctly 2`] = `
143
144
  "flexBasis": "14%",
144
145
  "height": 48,
145
146
  "justifyContent": "center",
146
- "width": 48,
147
+ "width": 120,
147
148
  },
148
149
  undefined,
149
150
  ]
150
151
  }
151
152
  testID="calendar-date-cell"
153
+ themeItemWidth={120}
152
154
  >
153
155
  <View
154
156
  accessibilityState={
@@ -2,15 +2,21 @@ import { fireEvent } from '@testing-library/react-native';
2
2
  import React from 'react';
3
3
  import Calendar from '..';
4
4
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
5
+ import { setOrientation } from '../../../testHelpers/utils';
5
6
 
6
7
  Date.now = jest.fn(() => new Date(2022, 10, 2).valueOf());
7
8
 
8
9
  describe('Calendar', () => {
9
- it('renders correctly', () => {
10
+ it.each`
11
+ orientation
12
+ ${'portrait'}
13
+ ${'landscape'}
14
+ `('renders correctly', ({ orientation }) => {
10
15
  const onChange = jest.fn();
11
16
  const onTitlePress = jest.fn();
12
17
  const onPreviousPress = jest.fn();
13
18
  const onNextPress = jest.fn();
19
+ setOrientation(orientation);
14
20
  const { getByText, queryAllByTestId, queryByTestId } = renderWithTheme(
15
21
  <Calendar
16
22
  value={new Date(2022, 10, 5)}
@@ -3,7 +3,7 @@ import {
3
3
  MonthYearPickerViewIOS,
4
4
  } from '@hero-design/react-native-month-year-picker';
5
5
  import format from 'date-fns/fp/format';
6
- import React from 'react';
6
+ import React, { useMemo, useState } from 'react';
7
7
  import { Platform, TouchableOpacity } from 'react-native';
8
8
  import { useTheme } from '../../theme';
9
9
  import { noop } from '../../utils/functions';
@@ -121,8 +121,13 @@ const Calendar = ({
121
121
  }),
122
122
  {}
123
123
  );
124
- const [monthPickerVisible, setMonthPickerVisible] = React.useState(false);
125
- const [contentHeight, setContentHeight] = React.useState(0);
124
+ const [monthPickerVisible, setMonthPickerVisible] = useState(false);
125
+ const [contentHeight, setContentHeight] = useState(0);
126
+ const [contentWidth, setContentWidth] = useState(0);
127
+ const calendarItemWidth = useMemo(
128
+ () => (contentWidth > 0 ? contentWidth / 7 : undefined),
129
+ [contentWidth]
130
+ );
126
131
 
127
132
  const useMonthPicker = onMonthChange !== noop;
128
133
 
@@ -241,6 +246,7 @@ const Calendar = ({
241
246
  theme.__hd__.calendar.space.iosPickerMarginVertical * 2,
242
247
  marginVertical:
243
248
  -theme.__hd__.calendar.space.iosPickerMarginVertical,
249
+ width: contentWidth,
244
250
  }}
245
251
  />
246
252
  </Box>
@@ -248,14 +254,18 @@ const Calendar = ({
248
254
  <Box
249
255
  onLayout={
250
256
  Platform.OS === 'ios'
251
- ? (e) => setContentHeight(e.nativeEvent.layout.height)
257
+ ? (e) => {
258
+ const { width, height } = e.nativeEvent.layout;
259
+ setContentHeight(height);
260
+ setContentWidth(width);
261
+ }
252
262
  : undefined
253
263
  }
254
264
  >
255
265
  <StyledCalendarRow>
256
266
  {DAYS_OF_WEEK.map((day) => (
257
267
  <StyledCalendarRowItem key={day}>
258
- <StyledCalendarDayNameCell>
268
+ <StyledCalendarDayNameCell themeItemWidth={calendarItemWidth}>
259
269
  <Typography.Body variant="small">{day}</Typography.Body>
260
270
  </StyledCalendarDayNameCell>
261
271
  </StyledCalendarRowItem>
@@ -272,14 +282,19 @@ const Calendar = ({
272
282
  onPress={() => onChange?.(date)}
273
283
  textIntent="subdued"
274
284
  marked={parsedMaskedDate[date.toDateString()]}
285
+ itemWidth={contentWidth > 0 ? contentWidth / 7 : undefined}
275
286
  />
276
287
  ) : (
277
- <StyledDisabledCalendarRowItem testID="calendar-disabled-cell" />
288
+ <StyledDisabledCalendarRowItem
289
+ themeItemWidth={calendarItemWidth}
290
+ testID="calendar-disabled-cell"
291
+ />
278
292
  )
279
293
  )}
280
294
  {daysOfCurrentMonth.map((date) =>
281
295
  date ? (
282
296
  <CalendarRowItem
297
+ itemWidth={calendarItemWidth}
283
298
  key={date.toDateString()}
284
299
  date={date}
285
300
  isCurrent={isEqDate(now, date)}
@@ -288,12 +303,16 @@ const Calendar = ({
288
303
  marked={parsedMaskedDate[date.toDateString()]}
289
304
  />
290
305
  ) : (
291
- <StyledDisabledCalendarRowItem testID="calendar-disabled-cell" />
306
+ <StyledDisabledCalendarRowItem
307
+ themeItemWidth={calendarItemWidth}
308
+ testID="calendar-disabled-cell"
309
+ />
292
310
  )
293
311
  )}
294
312
  {daysOfNextMonth.map((date) =>
295
313
  date ? (
296
314
  <CalendarRowItem
315
+ itemWidth={calendarItemWidth}
297
316
  key={date.toDateString()}
298
317
  date={date}
299
318
  isCurrent={isEqDate(now, date)}
@@ -303,7 +322,10 @@ const Calendar = ({
303
322
  marked={parsedMaskedDate[date.toDateString()]}
304
323
  />
305
324
  ) : (
306
- <StyledDisabledCalendarRowItem testID="calendar-disabled-cell" />
325
+ <StyledDisabledCalendarRowItem
326
+ themeItemWidth={calendarItemWidth}
327
+ testID="calendar-disabled-cell"
328
+ />
307
329
  )
308
330
  )}
309
331
  </StyledCalendarRow>
@@ -1,6 +1,6 @@
1
1
  import formatDate from 'date-fns/fp/format';
2
2
  import React, { useState } from 'react';
3
- import { Platform, TouchableOpacity, View } from 'react-native';
3
+ import { Platform, ScrollView, TouchableOpacity, View } from 'react-native';
4
4
 
5
5
  import BottomSheet from '../BottomSheet';
6
6
  import Button from '../Button';
@@ -77,6 +77,7 @@ const DatePickerCalendar = ({
77
77
  testID,
78
78
  monthPickerConfirmLabel,
79
79
  monthPickerCancelLabel,
80
+ supportedOrientations = ['portrait'],
80
81
  }: Omit<DatePickerProps, 'variant'>) => {
81
82
  const [open, setOpen] = useState(false);
82
83
  const [monthPickerVisible, setMonthPickerVisible] = useState(false);
@@ -121,16 +122,19 @@ const DatePickerCalendar = ({
121
122
  />
122
123
  )
123
124
  }
125
+ supportedOrientations={supportedOrientations}
124
126
  >
125
- <InternalCalendar
126
- minDate={minDate}
127
- maxDate={maxDate}
128
- value={value}
129
- onChange={setSelectingDate}
130
- monthPickerConfirmLabel={monthPickerConfirmLabel}
131
- monthPickerCancelLabel={monthPickerCancelLabel}
132
- onToggleMonthPicker={(visible) => setMonthPickerVisible(visible)}
133
- />
127
+ <ScrollView>
128
+ <InternalCalendar
129
+ minDate={minDate}
130
+ maxDate={maxDate}
131
+ value={value}
132
+ onChange={setSelectingDate}
133
+ monthPickerConfirmLabel={monthPickerConfirmLabel}
134
+ monthPickerCancelLabel={monthPickerCancelLabel}
135
+ onToggleMonthPicker={(visible) => setMonthPickerVisible(visible)}
136
+ />
137
+ </ScrollView>
134
138
  </BottomSheet>
135
139
  </TouchableOpacity>
136
140
  );
@@ -26,6 +26,7 @@ const DatePickerIOS = ({
26
26
  helpText,
27
27
  style,
28
28
  testID,
29
+ supportedOrientations = ['portrait'],
29
30
  }: Omit<
30
31
  DatePickerProps,
31
32
  'variant' | 'monthPickerConfirmLabel' | 'monthPickerCancelLabel'
@@ -71,6 +72,7 @@ const DatePickerIOS = ({
71
72
  }}
72
73
  />
73
74
  }
75
+ supportedOrientations={supportedOrientations}
74
76
  >
75
77
  <StyledPickerWrapper>
76
78
  <DateTimePicker
@@ -3,6 +3,7 @@ import React from 'react';
3
3
  import type { ModalProps } from 'react-native';
4
4
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
5
5
  import DatePickerCalendar from '../DatePickerCalendar';
6
+ import { setOrientation } from '../../../testHelpers/utils';
6
7
 
7
8
  jest.mock('react-native/Libraries/Modal/Modal', () => {
8
9
  const Modal = jest.requireActual('react-native/Libraries/Modal/Modal');
@@ -45,6 +46,42 @@ describe('DatePickerCalendar', () => {
45
46
  expect(onChange).toBeCalledWith(new Date('1995-12-14T00:00:00.000Z'));
46
47
  });
47
48
 
49
+ it('renders correctly in landscape mode', () => {
50
+ setOrientation('landscape');
51
+ const onChange = jest.fn();
52
+ const { getByText, queryByTestId } = renderWithTheme(
53
+ <DatePickerCalendar
54
+ value={new Date('1995-12-21T00:00:00.000Z')}
55
+ label="Start date"
56
+ confirmLabel="Confirm"
57
+ onChange={onChange}
58
+ supportedOrientations={['landscape']}
59
+ />
60
+ );
61
+
62
+ expect(getByText('Start date')).toBeDefined();
63
+ expect(queryByTestId('text-input').props.value).toBe('21/12/1995');
64
+ expect(queryByTestId('calendar')).toBeNull();
65
+
66
+ // Open date picker
67
+ fireEvent.press(getByText('Start date'));
68
+ expect(queryByTestId('calendar')).toBeTruthy();
69
+
70
+ expect(getByText('December 1995')).toBeDefined();
71
+ expect(getByText('Mo')).toBeDefined();
72
+ expect(getByText('Tu')).toBeDefined();
73
+ expect(getByText('We')).toBeDefined();
74
+ expect(getByText('Th')).toBeDefined();
75
+ expect(getByText('Fr')).toBeDefined();
76
+ expect(getByText('Sa')).toBeDefined();
77
+ expect(getByText('Su')).toBeDefined();
78
+ // Change date
79
+ fireEvent.press(getByText('14'));
80
+ fireEvent.press(getByText('Confirm'));
81
+
82
+ expect(onChange).toBeCalledWith(new Date('1995-12-14T00:00:00.000Z'));
83
+ });
84
+
48
85
  it('renders correct help text', () => {
49
86
  const { getByText } = renderWithTheme(
50
87
  <DatePickerCalendar
@@ -4,6 +4,7 @@ import type { ModalProps } from 'react-native';
4
4
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
5
5
  import DatePickerIOS from '../DatePickerIOS';
6
6
  import { getDateValue } from '../useCalculateDate';
7
+ import { setOrientation } from '../../../testHelpers/utils';
7
8
 
8
9
  jest.mock('react-native/Libraries/Modal/Modal', () => {
9
10
  const Modal = jest.requireActual('react-native/Libraries/Modal/Modal');
@@ -68,6 +69,39 @@ describe('DatePickerIOS', () => {
68
69
  expect(onChange).toBeCalledWith(new Date('December 17, 1995'));
69
70
  });
70
71
 
72
+ it('renders correctly in landscape mode', () => {
73
+ const onChange = jest.fn();
74
+ setOrientation('landscape');
75
+ const { getByText, queryByTestId } = renderWithTheme(
76
+ <DatePickerIOS
77
+ value={new Date('December 21, 1995')}
78
+ label="Start date"
79
+ confirmLabel="Confirm"
80
+ onChange={onChange}
81
+ supportedOrientations={['landscape']}
82
+ />
83
+ );
84
+
85
+ expect(getByText('Start date')).toBeDefined();
86
+ expect(queryByTestId('text-input').props.value).toBe('21/12/1995');
87
+ expect(queryByTestId('datePickerIOS')).toBeNull();
88
+
89
+ // Open date picker
90
+ fireEvent.press(getByText('Start date'));
91
+ expect(queryByTestId('datePickerIOS')).toBeTruthy();
92
+
93
+ // Change date
94
+ fireEvent(
95
+ queryByTestId('datePickerIOS'),
96
+ 'onChange',
97
+ null,
98
+ new Date('December 17, 1995')
99
+ );
100
+ fireEvent.press(getByText('Confirm'));
101
+
102
+ expect(onChange).toBeCalledWith(new Date('December 17, 1995'));
103
+ });
104
+
71
105
  it('renders correct help text', () => {
72
106
  const { getByText } = renderWithTheme(
73
107
  <DatePickerIOS
@@ -270,6 +270,11 @@ exports[`DatePickerIOS renders correctly 1`] = `
270
270
  "position": "absolute",
271
271
  }
272
272
  }
273
+ supportedOrientations={
274
+ [
275
+ "portrait",
276
+ ]
277
+ }
273
278
  transparent={true}
274
279
  visible={true}
275
280
  >
@@ -72,4 +72,8 @@ export interface DatePickerProps {
72
72
  * Calendar variant prop. Label for the cancel button of the month picker, Android only.
73
73
  */
74
74
  monthPickerCancelLabel?: string;
75
+ /**
76
+ * Supported orientations for the DatePicker modal, iOS only.
77
+ */
78
+ supportedOrientations?: ('portrait' | 'landscape')[];
75
79
  }
@@ -329,6 +329,11 @@ exports[`ActionGroup has active true 1`] = `
329
329
  animationType="fade"
330
330
  hardwareAccelerated={false}
331
331
  statusBarTranslucent={true}
332
+ supportedOrientations={
333
+ [
334
+ "portrait",
335
+ ]
336
+ }
332
337
  transparent={true}
333
338
  visible={true}
334
339
  >
@@ -1,39 +1,38 @@
1
1
  import '@testing-library/jest-native/extend-expect';
2
2
  import { fireEvent } from '@testing-library/react-native';
3
- import React from 'react';
3
+ import React, { ComponentProps } from 'react';
4
4
  import ActionGroup from '..';
5
5
  import renderWithTheme from '../../../../testHelpers/renderWithTheme';
6
+ import { setOrientation } from '../../../../testHelpers/utils';
6
7
 
7
8
  describe('ActionGroup', () => {
9
+ const items: ComponentProps<typeof ActionGroup>['items'] = [
10
+ {
11
+ icon: 'speaker',
12
+ title: 'Give shout out',
13
+ testID: 'speaker-action-item',
14
+ },
15
+ { icon: 'target', title: 'Goal', testID: 'target-action-item' },
16
+ {
17
+ icon: 'plane',
18
+ title: 'Leave request',
19
+ testID: 'plane-action-item',
20
+ },
21
+ {
22
+ icon: 'health-bag',
23
+ title: 'Safety incident',
24
+ testID: 'health-bag-action-item',
25
+ },
26
+ { icon: 'clock', title: 'Timesheets', testID: 'clock-action-item' },
27
+ ];
28
+
8
29
  it.each`
9
30
  active
10
31
  ${true}
11
32
  ${false}
12
33
  `('has active $active', ({ active }) => {
13
34
  const { toJSON, getByTestId, queryByTestId } = renderWithTheme(
14
- <ActionGroup
15
- fabTitle="Shout out"
16
- active={active}
17
- items={[
18
- {
19
- icon: 'speaker',
20
- title: 'Give shout out',
21
- testID: 'speaker-action-item',
22
- },
23
- { icon: 'target', title: 'Goal', testID: 'target-action-item' },
24
- {
25
- icon: 'plane',
26
- title: 'Leave request',
27
- testID: 'plane-action-item',
28
- },
29
- {
30
- icon: 'health-bag',
31
- title: 'Safety incident',
32
- testID: 'health-bag-action-item',
33
- },
34
- { icon: 'clock', title: 'Timesheets', testID: 'clock-action-item' },
35
- ]}
36
- />
35
+ <ActionGroup fabTitle="Shout out" active={active} items={items} />
37
36
  );
38
37
 
39
38
  expect(toJSON()).toMatchSnapshot();
@@ -51,6 +50,28 @@ describe('ActionGroup', () => {
51
50
  }
52
51
  });
53
52
 
53
+ it.each`
54
+ orientation
55
+ ${'portrait'}
56
+ ${'landscape'}
57
+ `('renders correctly in $orientation mode', ({ orientation }) => {
58
+ setOrientation(orientation);
59
+ const { getByTestId, queryByTestId } = renderWithTheme(
60
+ <ActionGroup
61
+ active
62
+ fabTitle="Shout out"
63
+ items={items}
64
+ supportedOrientations={[orientation]}
65
+ />
66
+ );
67
+
68
+ expect(queryByTestId('back-drop')).toBeDefined();
69
+ expect(getByTestId('speaker-action-item')).toBeDefined();
70
+ expect(getByTestId('target-action-item')).toBeDefined();
71
+ expect(getByTestId('plane-action-item')).toBeDefined();
72
+ expect(getByTestId('health-bag-action-item')).toBeDefined();
73
+ });
74
+
54
75
  describe('when user presses', () => {
55
76
  it('calls onPress when active = false', () => {
56
77
  const onPressSpy = jest.fn();
@@ -67,6 +67,10 @@ export interface ActionGroupProps {
67
67
  * Testing id of the component.
68
68
  */
69
69
  testID?: string;
70
+ /**
71
+ * Supported orientations for the ActionGroup modal, iOS only.
72
+ */
73
+ supportedOrientations?: ('portrait' | 'landscape')[];
70
74
  }
71
75
 
72
76
  const ActionGroup = forwardRef<ActionGroupHandles, ActionGroupProps>(
@@ -81,6 +85,7 @@ const ActionGroup = forwardRef<ActionGroupHandles, ActionGroupProps>(
81
85
  fabTitle,
82
86
  onBackdropPress,
83
87
  fabIcon = 'add',
88
+ supportedOrientations = ['portrait'],
84
89
  },
85
90
  ref
86
91
  ) => {
@@ -143,6 +148,7 @@ const ActionGroup = forwardRef<ActionGroupHandles, ActionGroupProps>(
143
148
  animationType="fade"
144
149
  transparent
145
150
  statusBarTranslucent
151
+ supportedOrientations={supportedOrientations}
146
152
  >
147
153
  <StyledContainerInModal testID={testID} style={[style]}>
148
154
  <StyledBackdrop testID="back-drop" onPress={onBackdropPress} />