@hero-design/rn 8.45.2-test-only.0 → 8.46.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.
@@ -3,6 +3,6 @@ $ rollup -c
3
3
  
4
4
  src/index.ts → lib/index.js, es/index.js...
5
5
  (!) Plugin replace: @rollup/plugin-replace: 'preventAssignment' currently defaults to false. It is recommended to set this option to `true`, as the next major version will default this option to `true`.
6
- (!) Plugin node-resolve: preferring built-in module 'events' over local alternative at '/runner/_work/hero-design/hero-design/node_modules/events/events.js', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
7
- created lib/index.js, es/index.js in 28.2s
6
+ (!) Plugin node-resolve: preferring built-in module 'events' over local alternative at '/root/hero-design/node_modules/events/events.js', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
7
+ created lib/index.js, es/index.js in 21.4s
8
8
  $ tsc --noEmit false --emitDeclarationOnly --project tsconfig.prod.json
package/CHANGELOG.md CHANGED
@@ -1,11 +1,26 @@
1
1
  # @hero-design/rn
2
2
 
3
- ## 8.45.2-test-only.0
3
+ ## 8.46.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#2426](https://github.com/Thinkei/hero-design/pull/2426) [`696e01db8`](https://github.com/Thinkei/hero-design/commit/696e01db8033379871d718dc20f5fdfb448a02e1) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [PageControl] Disable useNativeDriver to prevent crash
8
+
9
+ ## 8.46.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#2423](https://github.com/Thinkei/hero-design/pull/2423) [`176e43f0d`](https://github.com/Thinkei/hero-design/commit/176e43f0d2d50a67b053ddba8f8e5fb8d752599a) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [Swipeable] Add full-width variant
4
14
 
5
15
  ### Patch Changes
6
16
 
7
17
  - [#2406](https://github.com/Thinkei/hero-design/pull/2406) [`f6a11c2a9`](https://github.com/Thinkei/hero-design/commit/f6a11c2a97133154a527f607f3af59a5a7e30b3c) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [PageControl] Fix animation not working
8
18
 
19
+ - [#2407](https://github.com/Thinkei/hero-design/pull/2407) [`9b943f82d`](https://github.com/Thinkei/hero-design/commit/9b943f82dfa7a3213cb51ef32fc30c5ca77b3c5c) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [DatePicker] Update minDate and maxDate logic
20
+
21
+ - Updated dependencies [[`f006136ba`](https://github.com/Thinkei/hero-design/commit/f006136ba8db6d5adb9698c493e638338321c63c)]:
22
+ - @hero-design/colors@8.42.5
23
+
9
24
  ## 8.45.1
10
25
 
11
26
  ### Patch Changes
package/es/index.js CHANGED
@@ -11949,7 +11949,7 @@ var PageControl = function PageControl(_ref) {
11949
11949
  React.useEffect(function () {
11950
11950
  Animated.spring(animatedValue, {
11951
11951
  toValue: currentPage,
11952
- useNativeDriver: Platform.OS !== 'web'
11952
+ useNativeDriver: false // Native driver does not support animating width, it will cause the app to crash if set to true
11953
11953
  }).start();
11954
11954
  }, [currentPage]);
11955
11955
  return /*#__PURE__*/React.createElement(StyledPageControl$2, {
@@ -13083,6 +13083,28 @@ var TextInput = /*#__PURE__*/forwardRef(function (_ref2, ref) {
13083
13083
  }, displayText.length, "/", maxLength))));
13084
13084
  });
13085
13085
 
13086
+ var getDateValue = function getDateValue(value, minDate, maxDate) {
13087
+ if (minDate && value < minDate) {
13088
+ return minDate;
13089
+ }
13090
+ if (maxDate && value > maxDate) {
13091
+ return maxDate;
13092
+ }
13093
+ return value;
13094
+ };
13095
+ var useCalculateDate = function useCalculateDate(_ref) {
13096
+ var maxDate = _ref.maxDate,
13097
+ minDate = _ref.minDate,
13098
+ onChange = _ref.onChange,
13099
+ value = _ref.value;
13100
+ useEffect(function () {
13101
+ var newDate = getDateValue(value || new Date(), minDate, maxDate);
13102
+ if (newDate !== value) {
13103
+ onChange(newDate);
13104
+ }
13105
+ }, [maxDate, minDate, value]);
13106
+ };
13107
+
13086
13108
  var DatePickerAndroid = function DatePickerAndroid(_ref) {
13087
13109
  var value = _ref.value,
13088
13110
  minDate = _ref.minDate,
@@ -13105,6 +13127,12 @@ var DatePickerAndroid = function DatePickerAndroid(_ref) {
13105
13127
  setOpen = _useState2[1];
13106
13128
  var displayValue = value ? formatTime(displayFormat, value) : '';
13107
13129
  var pickerInitValue = value || new Date();
13130
+ useCalculateDate({
13131
+ minDate: minDate,
13132
+ maxDate: maxDate,
13133
+ onChange: _onChange,
13134
+ value: value
13135
+ });
13108
13136
  return /*#__PURE__*/React.createElement(TouchableOpacity, {
13109
13137
  onPress: function onPress() {
13110
13138
  return setOpen(true);
@@ -13217,6 +13245,12 @@ var DatePickerCalendar = function DatePickerCalendar(_ref2) {
13217
13245
  selectingDate = _useState10[0],
13218
13246
  setSelectingDate = _useState10[1];
13219
13247
  var displayValue = value ? formatTime(displayFormat, value) : '';
13248
+ useCalculateDate({
13249
+ minDate: minDate,
13250
+ maxDate: maxDate,
13251
+ onChange: onChange,
13252
+ value: value
13253
+ });
13220
13254
  return /*#__PURE__*/React.createElement(TouchableOpacity, {
13221
13255
  onPress: function onPress() {
13222
13256
  return setOpen(true);
@@ -13272,15 +13306,6 @@ var StyledPickerWrapper$1 = index$a(View)(function (_ref) {
13272
13306
  };
13273
13307
  });
13274
13308
 
13275
- var getInitialDateValue = function getInitialDateValue(value, minDate, maxDate) {
13276
- if (minDate && value < minDate) {
13277
- return minDate;
13278
- }
13279
- if (maxDate && value > maxDate) {
13280
- return maxDate;
13281
- }
13282
- return value;
13283
- };
13284
13309
  var DatePickerIOS = function DatePickerIOS(_ref) {
13285
13310
  var value = _ref.value,
13286
13311
  minDate = _ref.minDate,
@@ -13298,7 +13323,7 @@ var DatePickerIOS = function DatePickerIOS(_ref) {
13298
13323
  helpText = _ref.helpText,
13299
13324
  style = _ref.style,
13300
13325
  testID = _ref.testID;
13301
- var _useState = useState(getInitialDateValue(value || new Date(), minDate, maxDate)),
13326
+ var _useState = useState(getDateValue(value || new Date(), minDate, maxDate)),
13302
13327
  _useState2 = _slicedToArray(_useState, 2),
13303
13328
  selectingDate = _useState2[0],
13304
13329
  setSelectingDate = _useState2[1];
@@ -13308,6 +13333,12 @@ var DatePickerIOS = function DatePickerIOS(_ref) {
13308
13333
  setOpen = _useState4[1];
13309
13334
  var displayValue = value ? formatTime(displayFormat, value) : '';
13310
13335
  var theme = useTheme();
13336
+ useCalculateDate({
13337
+ minDate: minDate,
13338
+ maxDate: maxDate,
13339
+ onChange: onChange,
13340
+ value: value
13341
+ });
13311
13342
  return /*#__PURE__*/React.createElement(TouchableOpacity, {
13312
13343
  onPress: function onPress() {
13313
13344
  return setOpen(true);
@@ -15845,7 +15876,7 @@ var SwipeableAction = function SwipeableAction(_ref) {
15845
15876
  }, children);
15846
15877
  };
15847
15878
 
15848
- var _excluded$8 = ["children", "state", "onStateChange", "leftActions", "leftActionsWidth", "rightActions", "rightActionsWidth"];
15879
+ var _excluded$8 = ["children", "state", "onStateChange", "leftActions", "leftActionsWidth", "rightActions", "rightActionsWidth", "variant"];
15849
15880
  var renderActions = function renderActions(actions, width, progress, direction) {
15850
15881
  var trans = progress.interpolate({
15851
15882
  inputRange: [0, 1],
@@ -15870,6 +15901,8 @@ var Swipeable = function Swipeable(_ref) {
15870
15901
  leftActionsWidth = _ref.leftActionsWidth,
15871
15902
  rightActions = _ref.rightActions,
15872
15903
  rightActionsWidth = _ref.rightActionsWidth,
15904
+ _ref$variant = _ref.variant,
15905
+ variant = _ref$variant === void 0 ? 'card' : _ref$variant,
15873
15906
  swipeableProps = _objectWithoutProperties(_ref, _excluded$8);
15874
15907
  var theme = useTheme();
15875
15908
  var _useWindowDimensions = useWindowDimensions(),
@@ -15912,7 +15945,7 @@ var Swipeable = function Swipeable(_ref) {
15912
15945
  return onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange('closed');
15913
15946
  },
15914
15947
  containerStyle: {
15915
- borderRadius: theme.__hd__.swipeable.radii.swipeableContainer
15948
+ borderRadius: variant === 'card' ? theme.__hd__.swipeable.radii.swipeableContainer : 0
15916
15949
  }
15917
15950
  }), children));
15918
15951
  };
package/lib/index.js CHANGED
@@ -11979,7 +11979,7 @@ var PageControl = function PageControl(_ref) {
11979
11979
  React__default["default"].useEffect(function () {
11980
11980
  reactNative.Animated.spring(animatedValue, {
11981
11981
  toValue: currentPage,
11982
- useNativeDriver: reactNative.Platform.OS !== 'web'
11982
+ useNativeDriver: false // Native driver does not support animating width, it will cause the app to crash if set to true
11983
11983
  }).start();
11984
11984
  }, [currentPage]);
11985
11985
  return /*#__PURE__*/React__default["default"].createElement(StyledPageControl$2, {
@@ -13113,6 +13113,28 @@ var TextInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
13113
13113
  }, displayText.length, "/", maxLength))));
13114
13114
  });
13115
13115
 
13116
+ var getDateValue = function getDateValue(value, minDate, maxDate) {
13117
+ if (minDate && value < minDate) {
13118
+ return minDate;
13119
+ }
13120
+ if (maxDate && value > maxDate) {
13121
+ return maxDate;
13122
+ }
13123
+ return value;
13124
+ };
13125
+ var useCalculateDate = function useCalculateDate(_ref) {
13126
+ var maxDate = _ref.maxDate,
13127
+ minDate = _ref.minDate,
13128
+ onChange = _ref.onChange,
13129
+ value = _ref.value;
13130
+ React.useEffect(function () {
13131
+ var newDate = getDateValue(value || new Date(), minDate, maxDate);
13132
+ if (newDate !== value) {
13133
+ onChange(newDate);
13134
+ }
13135
+ }, [maxDate, minDate, value]);
13136
+ };
13137
+
13116
13138
  var DatePickerAndroid = function DatePickerAndroid(_ref) {
13117
13139
  var value = _ref.value,
13118
13140
  minDate = _ref.minDate,
@@ -13135,6 +13157,12 @@ var DatePickerAndroid = function DatePickerAndroid(_ref) {
13135
13157
  setOpen = _useState2[1];
13136
13158
  var displayValue = value ? formatTime(displayFormat, value) : '';
13137
13159
  var pickerInitValue = value || new Date();
13160
+ useCalculateDate({
13161
+ minDate: minDate,
13162
+ maxDate: maxDate,
13163
+ onChange: _onChange,
13164
+ value: value
13165
+ });
13138
13166
  return /*#__PURE__*/React__default["default"].createElement(reactNative.TouchableOpacity, {
13139
13167
  onPress: function onPress() {
13140
13168
  return setOpen(true);
@@ -13247,6 +13275,12 @@ var DatePickerCalendar = function DatePickerCalendar(_ref2) {
13247
13275
  selectingDate = _useState10[0],
13248
13276
  setSelectingDate = _useState10[1];
13249
13277
  var displayValue = value ? formatTime(displayFormat, value) : '';
13278
+ useCalculateDate({
13279
+ minDate: minDate,
13280
+ maxDate: maxDate,
13281
+ onChange: onChange,
13282
+ value: value
13283
+ });
13250
13284
  return /*#__PURE__*/React__default["default"].createElement(reactNative.TouchableOpacity, {
13251
13285
  onPress: function onPress() {
13252
13286
  return setOpen(true);
@@ -13302,15 +13336,6 @@ var StyledPickerWrapper$1 = index$a(reactNative.View)(function (_ref) {
13302
13336
  };
13303
13337
  });
13304
13338
 
13305
- var getInitialDateValue = function getInitialDateValue(value, minDate, maxDate) {
13306
- if (minDate && value < minDate) {
13307
- return minDate;
13308
- }
13309
- if (maxDate && value > maxDate) {
13310
- return maxDate;
13311
- }
13312
- return value;
13313
- };
13314
13339
  var DatePickerIOS = function DatePickerIOS(_ref) {
13315
13340
  var value = _ref.value,
13316
13341
  minDate = _ref.minDate,
@@ -13328,7 +13353,7 @@ var DatePickerIOS = function DatePickerIOS(_ref) {
13328
13353
  helpText = _ref.helpText,
13329
13354
  style = _ref.style,
13330
13355
  testID = _ref.testID;
13331
- var _useState = React.useState(getInitialDateValue(value || new Date(), minDate, maxDate)),
13356
+ var _useState = React.useState(getDateValue(value || new Date(), minDate, maxDate)),
13332
13357
  _useState2 = _slicedToArray(_useState, 2),
13333
13358
  selectingDate = _useState2[0],
13334
13359
  setSelectingDate = _useState2[1];
@@ -13338,6 +13363,12 @@ var DatePickerIOS = function DatePickerIOS(_ref) {
13338
13363
  setOpen = _useState4[1];
13339
13364
  var displayValue = value ? formatTime(displayFormat, value) : '';
13340
13365
  var theme = useTheme();
13366
+ useCalculateDate({
13367
+ minDate: minDate,
13368
+ maxDate: maxDate,
13369
+ onChange: onChange,
13370
+ value: value
13371
+ });
13341
13372
  return /*#__PURE__*/React__default["default"].createElement(reactNative.TouchableOpacity, {
13342
13373
  onPress: function onPress() {
13343
13374
  return setOpen(true);
@@ -15875,7 +15906,7 @@ var SwipeableAction = function SwipeableAction(_ref) {
15875
15906
  }, children);
15876
15907
  };
15877
15908
 
15878
- var _excluded$8 = ["children", "state", "onStateChange", "leftActions", "leftActionsWidth", "rightActions", "rightActionsWidth"];
15909
+ var _excluded$8 = ["children", "state", "onStateChange", "leftActions", "leftActionsWidth", "rightActions", "rightActionsWidth", "variant"];
15879
15910
  var renderActions = function renderActions(actions, width, progress, direction) {
15880
15911
  var trans = progress.interpolate({
15881
15912
  inputRange: [0, 1],
@@ -15900,6 +15931,8 @@ var Swipeable = function Swipeable(_ref) {
15900
15931
  leftActionsWidth = _ref.leftActionsWidth,
15901
15932
  rightActions = _ref.rightActions,
15902
15933
  rightActionsWidth = _ref.rightActionsWidth,
15934
+ _ref$variant = _ref.variant,
15935
+ variant = _ref$variant === void 0 ? 'card' : _ref$variant,
15903
15936
  swipeableProps = _objectWithoutProperties(_ref, _excluded$8);
15904
15937
  var theme = useTheme();
15905
15938
  var _useWindowDimensions = reactNative.useWindowDimensions(),
@@ -15942,7 +15975,7 @@ var Swipeable = function Swipeable(_ref) {
15942
15975
  return onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange('closed');
15943
15976
  },
15944
15977
  containerStyle: {
15945
- borderRadius: theme.__hd__.swipeable.radii.swipeableContainer
15978
+ borderRadius: variant === 'card' ? theme.__hd__.swipeable.radii.swipeableContainer : 0
15946
15979
  }
15947
15980
  }), children));
15948
15981
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.45.2-test-only.0",
3
+ "version": "8.46.1",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "@emotion/native": "^11.9.3",
23
23
  "@emotion/react": "^11.9.3",
24
- "@hero-design/colors": "8.42.4",
24
+ "@hero-design/colors": "8.42.5",
25
25
  "date-fns": "^2.16.1",
26
26
  "events": "^3.2.0",
27
27
  "hero-editor": "^1.9.21",
@@ -1,10 +1,11 @@
1
1
  import DateTimePicker from '@react-native-community/datetimepicker';
2
+ import formatDate from 'date-fns/fp/format';
2
3
  import React, { useState } from 'react';
3
4
  import { TouchableOpacity, View } from 'react-native';
4
- import formatDate from 'date-fns/fp/format';
5
5
 
6
6
  import TextInput from '../TextInput';
7
7
  import type { DatePickerProps } from './types';
8
+ import useCalculateDate from './useCalculateDate';
8
9
 
9
10
  const DatePickerAndroid = ({
10
11
  value,
@@ -25,10 +26,11 @@ const DatePickerAndroid = ({
25
26
  'variant' | 'monthPickerConfirmLabel' | 'monthPickerCancelLabel'
26
27
  >) => {
27
28
  const [open, setOpen] = useState(false);
28
-
29
29
  const displayValue = value ? formatDate(displayFormat, value) : '';
30
30
  const pickerInitValue = value || new Date();
31
31
 
32
+ useCalculateDate({ minDate, maxDate, onChange, value });
33
+
32
34
  return (
33
35
  <TouchableOpacity onPress={() => setOpen(true)} disabled={disabled}>
34
36
  <View pointerEvents="none" testID="datePickerInputAndroid">
@@ -7,6 +7,7 @@ import Button from '../Button';
7
7
  import Calendar, { CalendarProps } from '../Calendar';
8
8
  import TextInput from '../TextInput';
9
9
  import type { DatePickerProps } from './types';
10
+ import useCalculateDate from './useCalculateDate';
10
11
 
11
12
  const InternalCalendar = ({
12
13
  minDate,
@@ -84,6 +85,8 @@ const DatePickerCalendar = ({
84
85
  const [selectingDate, setSelectingDate] = useState<Date>(value || new Date());
85
86
  const displayValue = value ? formatDate(displayFormat, value) : '';
86
87
 
88
+ useCalculateDate({ minDate, maxDate, onChange, value });
89
+
87
90
  return (
88
91
  <TouchableOpacity onPress={() => setOpen(true)} disabled={disabled}>
89
92
  <View pointerEvents="none" testID="datePickerCalendar">
@@ -1,30 +1,15 @@
1
1
  import DateTimePicker from '@react-native-community/datetimepicker';
2
+ import formatDate from 'date-fns/fp/format';
2
3
  import React, { useState } from 'react';
3
4
  import { TouchableOpacity, View } from 'react-native';
4
- import formatDate from 'date-fns/fp/format';
5
5
 
6
+ import { useTheme } from '../../theme';
6
7
  import BottomSheet from '../BottomSheet';
7
- import TextInput from '../TextInput';
8
8
  import Button from '../Button';
9
+ import TextInput from '../TextInput';
9
10
  import { StyledPickerWrapper } from './StyledDatePicker';
10
11
  import type { DatePickerProps } from './types';
11
- import { useTheme } from '../../theme';
12
-
13
- export const getInitialDateValue = (
14
- value: Date,
15
- minDate?: Date | undefined,
16
- maxDate?: Date | undefined
17
- ) => {
18
- if (minDate && value < minDate) {
19
- return minDate;
20
- }
21
-
22
- if (maxDate && value > maxDate) {
23
- return maxDate;
24
- }
25
-
26
- return value;
27
- };
12
+ import useCalculateDate, { getDateValue } from './useCalculateDate';
28
13
 
29
14
  const DatePickerIOS = ({
30
15
  value,
@@ -46,13 +31,14 @@ const DatePickerIOS = ({
46
31
  'variant' | 'monthPickerConfirmLabel' | 'monthPickerCancelLabel'
47
32
  >) => {
48
33
  const [selectingDate, setSelectingDate] = useState<Date>(
49
- getInitialDateValue(value || new Date(), minDate, maxDate)
34
+ getDateValue(value || new Date(), minDate, maxDate)
50
35
  );
51
36
  const [open, setOpen] = useState(false);
52
-
53
37
  const displayValue = value ? formatDate(displayFormat, value) : '';
54
-
55
38
  const theme = useTheme();
39
+
40
+ useCalculateDate({ minDate, maxDate, onChange, value });
41
+
56
42
  return (
57
43
  <TouchableOpacity onPress={() => setOpen(true)} disabled={disabled}>
58
44
  <View pointerEvents="none" testID="datePickerInputIOS">
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
2
  import { Platform } from 'react-native';
3
+ import { fireEvent } from '@testing-library/react-native';
3
4
  import DatePicker from '..';
4
5
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
6
+ import { Button } from '../../..';
5
7
 
6
8
  describe('DatePicker', () => {
7
9
  it('renders DatePickerIOS when OS is iOS', () => {
@@ -54,4 +56,94 @@ describe('DatePicker', () => {
54
56
  expect(toJSON()).toMatchSnapshot();
55
57
  expect(getByTestId('datePickerCalendar')).toBeDefined();
56
58
  });
59
+
60
+ it.each`
61
+ OS | variant
62
+ ${'ios'} | ${'calendar'}
63
+ ${'android'} | ${'calendar'}
64
+ ${'ios'} | ${'default'}
65
+ ${'android'} | ${'default'}
66
+ `(
67
+ 'changes value when minDate changes with OS=$OS and variant=$variant',
68
+ ({ OS, variant }) => {
69
+ Platform.OS = OS;
70
+ const DatePickerExample = () => {
71
+ const [minDate, setMinDate] = React.useState<Date | undefined>(
72
+ new Date('2000-01-01')
73
+ );
74
+ const [value, setValue] = React.useState<Date | undefined>(
75
+ new Date('December 21, 1995')
76
+ );
77
+
78
+ return (
79
+ <>
80
+ <Button
81
+ onPress={() => setMinDate(new Date('2023-11-01'))}
82
+ text="Change min date"
83
+ />
84
+
85
+ <DatePicker
86
+ value={value}
87
+ minDate={minDate}
88
+ label="Start date"
89
+ confirmLabel="Confirm"
90
+ onChange={(date) => setValue(date)}
91
+ variant={variant}
92
+ />
93
+ </>
94
+ );
95
+ };
96
+
97
+ const { getByText, queryByDisplayValue } = renderWithTheme(
98
+ <DatePickerExample />
99
+ );
100
+
101
+ expect(queryByDisplayValue('01/01/2000')).toBeTruthy();
102
+
103
+ fireEvent.press(getByText('Change min date'));
104
+ expect(queryByDisplayValue('01/11/2023')).toBeTruthy();
105
+ }
106
+ );
107
+
108
+ it.each`
109
+ OS
110
+ ${'ios'}
111
+ ${'android'}
112
+ `('changes value when maxDate changes with OS=$OS', ({ OS }) => {
113
+ Platform.OS = OS;
114
+ const DatePickerExample = () => {
115
+ const [maxDate, setMaxDate] = React.useState<Date | undefined>(
116
+ new Date('1996-12-21')
117
+ );
118
+ const [value, setValue] = React.useState<Date | undefined>(
119
+ new Date('December 21, 1997')
120
+ );
121
+
122
+ return (
123
+ <>
124
+ <Button
125
+ onPress={() => setMaxDate(new Date('1994-12-21'))}
126
+ text="Change max date"
127
+ />
128
+
129
+ <DatePicker
130
+ value={value}
131
+ maxDate={maxDate}
132
+ label="Start date"
133
+ confirmLabel="Confirm"
134
+ onChange={(date) => setValue(date)}
135
+ />
136
+ </>
137
+ );
138
+ };
139
+
140
+ const { getByText, queryByDisplayValue } = renderWithTheme(
141
+ <DatePickerExample />
142
+ );
143
+
144
+ expect(queryByDisplayValue('21/12/1996')).toBeTruthy();
145
+
146
+ fireEvent.press(getByText('Change max date'));
147
+ expect(queryByDisplayValue('21/12/1994')).toBeTruthy();
148
+ });
57
149
  });
@@ -2,26 +2,27 @@ import { fireEvent } from '@testing-library/react-native';
2
2
  import React from 'react';
3
3
  import type { ModalProps } from 'react-native';
4
4
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
5
- import DatePickerIOS, { getInitialDateValue } from '../DatePickerIOS';
5
+ import DatePickerIOS from '../DatePickerIOS';
6
+ import { getDateValue } from '../useCalculateDate';
6
7
 
7
8
  jest.mock('react-native/Libraries/Modal/Modal', () => {
8
9
  const Modal = jest.requireActual('react-native/Libraries/Modal/Modal');
9
10
  return (props: ModalProps) => <Modal {...props} />;
10
11
  });
11
12
 
12
- describe('getInitialDateValue', () => {
13
+ describe('getDateValue', () => {
13
14
  describe('when value is less than minDate', () => {
14
15
  it('should return minDate', () => {
15
16
  const value = new Date('2022-01-01T00:00:00.000Z');
16
17
  const minDate = new Date('2025-01-01T00:00:00.000Z');
17
- expect(getInitialDateValue(value, minDate)).toBe(minDate);
18
+ expect(getDateValue(value, minDate)).toBe(minDate);
18
19
  });
19
20
  });
20
21
  describe('when value is greater than maxDate', () => {
21
22
  it('should return maxDate', () => {
22
23
  const value = new Date('2025-01-01T00:00:00.000Z');
23
24
  const maxDate = new Date('2022-01-01T00:00:00.000Z');
24
- expect(getInitialDateValue(value, undefined, maxDate)).toBe(maxDate);
25
+ expect(getDateValue(value, undefined, maxDate)).toBe(maxDate);
25
26
  });
26
27
  });
27
28
  describe('when minDate < value < maxDate', () => {
@@ -29,7 +30,7 @@ describe('getInitialDateValue', () => {
29
30
  const minDate = new Date('2022-01-01T00:00:00.000Z');
30
31
  const value = new Date('2023-01-01T00:00:00.000Z');
31
32
  const maxDate = new Date('2025-01-01T00:00:00.000Z');
32
- expect(getInitialDateValue(value, minDate, maxDate)).toBe(value);
33
+ expect(getDateValue(value, minDate, maxDate)).toBe(value);
33
34
  });
34
35
  });
35
36
  });
@@ -0,0 +1,34 @@
1
+ import { useEffect } from 'react';
2
+ import { DatePickerProps } from './types';
3
+
4
+ export const getDateValue = (
5
+ value: Date,
6
+ minDate?: Date | undefined,
7
+ maxDate?: Date | undefined
8
+ ) => {
9
+ if (minDate && value < minDate) {
10
+ return minDate;
11
+ }
12
+
13
+ if (maxDate && value > maxDate) {
14
+ return maxDate;
15
+ }
16
+
17
+ return value;
18
+ };
19
+
20
+ const useCalculateDate = ({
21
+ maxDate,
22
+ minDate,
23
+ onChange,
24
+ value,
25
+ }: Pick<DatePickerProps, 'maxDate' | 'minDate' | 'onChange' | 'value'>) => {
26
+ useEffect(() => {
27
+ const newDate = getDateValue(value || new Date(), minDate, maxDate);
28
+ if (newDate !== value) {
29
+ onChange(newDate);
30
+ }
31
+ }, [maxDate, minDate, value]);
32
+ };
33
+
34
+ export default useCalculateDate;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { Animated, Platform, StyleProp, ViewStyle } from 'react-native';
2
+ import { Animated, StyleProp, ViewStyle } from 'react-native';
3
3
 
4
+ import { useTheme } from '../../theme';
4
5
  import {
5
- StyledPageControlAnimatedView,
6
6
  StyledPageControl,
7
+ StyledPageControlAnimatedView,
7
8
  } from './StyledPageControl';
8
- import { useTheme } from '../../theme';
9
9
 
10
10
  export interface PageControlProps {
11
11
  /**
@@ -37,7 +37,7 @@ const PageControl = ({
37
37
  React.useEffect(() => {
38
38
  Animated.spring(animatedValue, {
39
39
  toValue: currentPage,
40
- useNativeDriver: Platform.OS !== 'web',
40
+ useNativeDriver: false, // Native driver does not support animating width, it will cause the app to crash if set to true
41
41
  }).start();
42
42
  }, [currentPage]);
43
43
 
@@ -1,6 +1,6 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`Swipeable renders correctly 1`] = `
3
+ exports[`Swipeable renders correctly with variant=card 1`] = `
4
4
  <View
5
5
  style={
6
6
  {
@@ -65,3 +65,69 @@ exports[`Swipeable renders correctly 1`] = `
65
65
  />
66
66
  </View>
67
67
  `;
68
+
69
+ exports[`Swipeable renders correctly with variant=full-width 1`] = `
70
+ <View
71
+ style={
72
+ {
73
+ "flex": 1,
74
+ }
75
+ }
76
+ >
77
+ <View>
78
+ <View
79
+ containerStyle={
80
+ {
81
+ "borderRadius": 0,
82
+ }
83
+ }
84
+ onSwipeableClose={[Function]}
85
+ onSwipeableLeftOpen={[Function]}
86
+ onSwipeableRightOpen={[Function]}
87
+ renderLeftActions={[Function]}
88
+ renderRightActions={[Function]}
89
+ >
90
+ <Text
91
+ allowFontScaling={false}
92
+ style={
93
+ [
94
+ {
95
+ "color": "#001f23",
96
+ "fontFamily": "BeVietnamPro-Regular",
97
+ "fontSize": 14,
98
+ "letterSpacing": 0.48,
99
+ "lineHeight": 22,
100
+ },
101
+ undefined,
102
+ ]
103
+ }
104
+ themeIntent="body"
105
+ themeTypeface="neutral"
106
+ themeVariant="small"
107
+ >
108
+ Swipeable Item
109
+ </Text>
110
+ </View>
111
+ </View>
112
+ <View
113
+ pointerEvents="box-none"
114
+ position="bottom"
115
+ style={
116
+ [
117
+ {
118
+ "bottom": 0,
119
+ "elevation": 9999,
120
+ "flexDirection": "column-reverse",
121
+ "left": 0,
122
+ "paddingHorizontal": 24,
123
+ "paddingVertical": 16,
124
+ "position": "absolute",
125
+ "right": 0,
126
+ "top": 0,
127
+ },
128
+ undefined,
129
+ ]
130
+ }
131
+ />
132
+ </View>
133
+ `;
@@ -4,7 +4,11 @@ import Typography from '../../Typography';
4
4
  import Swipeable from '..';
5
5
 
6
6
  describe('Swipeable', () => {
7
- it('renders correctly', () => {
7
+ it.each`
8
+ variant
9
+ ${'card'}
10
+ ${'full-width'}
11
+ `('renders correctly with variant=$variant', ({ variant }) => {
8
12
  const { toJSON, getByText } = renderWithTheme(
9
13
  <Swipeable
10
14
  leftActions={
@@ -25,6 +29,7 @@ describe('Swipeable', () => {
25
29
  </>
26
30
  }
27
31
  rightActionsWidth={168}
32
+ variant={variant}
28
33
  >
29
34
  <Typography.Body variant="small">Swipeable Item</Typography.Body>
30
35
  </Swipeable>
@@ -66,6 +66,10 @@ export interface SwipeableProps
66
66
  * Testing ID of the component
67
67
  */
68
68
  testID?: string;
69
+ /**
70
+ * Variant of the component.
71
+ */
72
+ variant?: 'card' | 'full-width';
69
73
  }
70
74
 
71
75
  const renderActions = (
@@ -101,6 +105,7 @@ const Swipeable = ({
101
105
  leftActionsWidth,
102
106
  rightActions,
103
107
  rightActionsWidth,
108
+ variant = 'card',
104
109
  ...swipeableProps
105
110
  }: SwipeableProps) => {
106
111
  const theme = useTheme();
@@ -150,7 +155,10 @@ const Swipeable = ({
150
155
  onSwipeableRightOpen={() => onStateChange?.('rightOpen')}
151
156
  onSwipeableClose={() => onStateChange?.('closed')}
152
157
  containerStyle={{
153
- borderRadius: theme.__hd__.swipeable.radii.swipeableContainer,
158
+ borderRadius:
159
+ variant === 'card'
160
+ ? theme.__hd__.swipeable.radii.swipeableContainer
161
+ : 0,
154
162
  }}
155
163
  >
156
164
  {children}
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
2
  import type { DatePickerProps } from './types';
3
- export declare const getInitialDateValue: (value: Date, minDate?: Date | undefined, maxDate?: Date | undefined) => Date;
4
3
  declare const DatePickerIOS: ({ value, minDate, maxDate, label, placeholder, onChange, confirmLabel, displayFormat, disabled, required, error, helpText, style, testID, }: Omit<DatePickerProps, 'variant' | 'monthPickerConfirmLabel' | 'monthPickerCancelLabel'>) => React.JSX.Element;
5
4
  export default DatePickerIOS;
@@ -0,0 +1,4 @@
1
+ import { DatePickerProps } from './types';
2
+ export declare const getDateValue: (value: Date, minDate?: Date | undefined, maxDate?: Date | undefined) => Date;
3
+ declare const useCalculateDate: ({ maxDate, minDate, onChange, value, }: Pick<DatePickerProps, 'maxDate' | 'minDate' | 'onChange' | 'value'>) => void;
4
+ export default useCalculateDate;
@@ -37,8 +37,12 @@ export interface SwipeableProps extends Pick<RnghSwipeableProps, 'enableTrackpad
37
37
  * Testing ID of the component
38
38
  */
39
39
  testID?: string;
40
+ /**
41
+ * Variant of the component.
42
+ */
43
+ variant?: 'card' | 'full-width';
40
44
  }
41
- declare const _default: (({ children, state, onStateChange, leftActions, leftActionsWidth, rightActions, rightActionsWidth, ...swipeableProps }: SwipeableProps) => React.JSX.Element) & {
45
+ declare const _default: (({ children, state, onStateChange, leftActions, leftActionsWidth, rightActions, rightActionsWidth, variant, ...swipeableProps }: SwipeableProps) => React.JSX.Element) & {
42
46
  Action: ({ intent, onPress, style, children, testID, }: import("./SwipeableAction").SwipeableActionProps) => React.JSX.Element;
43
47
  Content: typeof RectButton;
44
48
  };