@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.
- package/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +12 -0
- package/es/index.js +85 -38
- package/lib/index.js +85 -38
- package/package.json +1 -1
- package/src/components/BottomSheet/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
- package/src/components/BottomSheet/__tests__/index.spec.tsx +17 -0
- package/src/components/BottomSheet/index.tsx +6 -0
- package/src/components/Calendar/CalendarRowItem.tsx +3 -1
- package/src/components/Calendar/StyledCalendar.tsx +21 -8
- package/src/components/Calendar/__tests__/CalendarRowItem.spec.tsx +1 -0
- package/src/components/Calendar/__tests__/__snapshots__/CalendarRowItem.spec.tsx.snap +4 -2
- package/src/components/Calendar/__tests__/index.spec.tsx +7 -1
- package/src/components/Calendar/index.tsx +30 -8
- package/src/components/DatePicker/DatePickerCalendar.tsx +14 -10
- package/src/components/DatePicker/DatePickerIOS.tsx +2 -0
- package/src/components/DatePicker/__tests__/DatePickerCalendar.spec.tsx +37 -0
- package/src/components/DatePicker/__tests__/DatePickerIOS.spec.tsx +34 -0
- package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +5 -0
- package/src/components/DatePicker/types.ts +4 -0
- package/src/components/FAB/ActionGroup/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
- package/src/components/FAB/ActionGroup/__tests__/index.spec.tsx +45 -24
- package/src/components/FAB/ActionGroup/index.tsx +6 -0
- package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +20 -0
- package/src/components/Select/MultiSelect/__tests__/index.spec.tsx +28 -0
- package/src/components/Select/MultiSelect/index.tsx +6 -0
- package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +15 -0
- package/src/components/Select/SingleSelect/__tests__/index.spec.tsx +25 -0
- package/src/components/Select/SingleSelect/index.tsx +6 -0
- package/src/components/TimePicker/TimePickerIOS.tsx +2 -0
- package/src/components/TimePicker/__tests__/TimePickerIOS.spec.tsx +31 -0
- package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +5 -0
- package/src/components/TimePicker/types.ts +4 -0
- package/src/testHelpers/utils.ts +21 -0
- package/stats/8.64.0/rn-stats.html +4844 -0
- package/stats/8.64.1/rn-stats.html +4842 -0
- package/types/components/BottomSheet/index.d.ts +5 -1
- package/types/components/Calendar/CalendarRowItem.d.ts +2 -1
- package/types/components/Calendar/StyledCalendar.d.ts +7 -0
- package/types/components/DatePicker/DatePickerCalendar.d.ts +1 -1
- package/types/components/DatePicker/DatePickerIOS.d.ts +1 -1
- package/types/components/DatePicker/types.d.ts +4 -0
- package/types/components/FAB/ActionGroup/index.d.ts +4 -0
- package/types/components/Select/MultiSelect/index.d.ts +5 -1
- package/types/components/Select/SingleSelect/index.d.ts +5 -1
- package/types/components/Select/index.d.ts +1 -1
- package/types/components/TimePicker/TimePickerIOS.d.ts +1 -1
- package/types/components/TimePicker/types.d.ts +4 -0
package/package.json
CHANGED
|
@@ -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)<
|
|
16
|
-
|
|
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
|
-
|
|
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)<
|
|
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)<
|
|
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
|
|
|
@@ -16,12 +16,13 @@ exports[`CalendarRowItem renders correctly 1`] = `
|
|
|
16
16
|
"flexBasis": "14%",
|
|
17
17
|
"height": 48,
|
|
18
18
|
"justifyContent": "center",
|
|
19
|
-
"width":
|
|
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":
|
|
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
|
|
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] =
|
|
125
|
-
const [contentHeight, setContentHeight] =
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
|
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
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
|
@@ -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
|
}
|
|
@@ -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} />
|