diff --git a/README.md b/README.md
index 615c4d3..0c15822 100644
--- a/README.md
+++ b/README.md
@@ -31,24 +31,22 @@ import { View, Button, Text } from 'react-native';
import MonthPicker from 'react-native-month-year-picker';
const App = () => {
+ const [date, setDate] = useState(new Date());
- const [show, setShow] = useState(false);
- const [date, setDate] = useState();
-
- const toggleMonthPicker = () => setShow(!show);
-
- const onValueChange = (event, value) => setDate(value);
+ const onValueChange = (event, newDate) => setDate(newDate);
return (
-
-
- `The selected date is: ${date}`
- {show && (
-
- )}
-
- )
-}
+
+ Month Picker Example
+
+
+ );
+};
export default App;
@@ -78,7 +76,7 @@ Defines the date value used in the component.
#### `maximumDate` (`optional`)
-Defines the maximum date that can be selected.
+Defines the maximum date that can be selected. Use year and month constructor.
```js
@@ -86,7 +84,7 @@ Defines the maximum date that can be selected.
#### `minimumDate` (`optional`)
-Defines the minimum date that can be selected.
+Defines the minimum date that can be selected. Use year and month constructor.
```js
diff --git a/example/App.js b/example/App.js
index 3dea0cc..76226a4 100644
--- a/example/App.js
+++ b/example/App.js
@@ -16,13 +16,19 @@ const styles = StyleSheet.create({
});
const App = () => {
- const [date, setDate] = useState(null);
+ const [date, setDate] = useState(new Date());
+
+ const onValueChange = (event, newDate) => setDate(newDate);
return (
Month Picker Example
- {date}
-
+
);
};
diff --git a/example/index.js b/example/index.js
index a850d03..9b73932 100644
--- a/example/index.js
+++ b/example/index.js
@@ -2,8 +2,8 @@
* @format
*/
-import {AppRegistry} from 'react-native';
+import { AppRegistry } from 'react-native';
import App from './App';
-import {name as appName} from './app.json';
+import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index a62aa83..8a5cdd6 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -233,7 +233,7 @@ PODS:
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsinspector (0.62.2)
- - react-native-month-year-picker (1.0.0):
+ - react-native-month-year-picker (1.0.1):
- React
- React-RCTActionSheet (0.62.2):
- React-Core/RCTActionSheetHeaders (= 0.62.2)
@@ -443,7 +443,7 @@ SPEC CHECKSUMS:
React-jsi: b6dc94a6a12ff98e8877287a0b7620d365201161
React-jsiexecutor: 1540d1c01bb493ae3124ed83351b1b6a155db7da
React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493
- react-native-month-year-picker: c800ca806e87bcee6527695815d9f109dc16cc62
+ react-native-month-year-picker: 7dd62f9c53021394a7cead6f1ffaa3b7946790c9
React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c
React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0
React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71
diff --git a/ios/RNMonthPicker.h b/ios/RNMonthPicker.h
index 42fcd76..c78caef 100644
--- a/ios/RNMonthPicker.h
+++ b/ios/RNMonthPicker.h
@@ -13,8 +13,8 @@
@interface RNMonthPicker : UIPickerView
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
-@property (nonatomic, strong) NSDate* value;
-@property (nonatomic, strong) NSDate* minimumDate;
-@property (nonatomic, strong) NSDate* maximumDate;
+@property (nonatomic, assign) NSDate* value;
+@property (nonatomic, assign) NSDate* minimumDate;
+@property (nonatomic, assign) NSDate* maximumDate;
@end
diff --git a/ios/RNMonthPicker.m b/ios/RNMonthPicker.m
index b9d7a72..ab13467 100644
--- a/ios/RNMonthPicker.m
+++ b/ios/RNMonthPicker.m
@@ -11,7 +11,7 @@
#import
#import
-#define DEFAULT_SIZE 204
+#define DEFAULT_SIZE 408
@interface RNMonthPicker()
@end
@@ -19,6 +19,8 @@ @interface RNMonthPicker()
@implementation RNMonthPicker
NSCalendar *gregorian;
+NSDateComponents *maxComponents;
+NSDateComponents *minComponents;
NSMutableArray *months;
NSMutableArray *years;
@@ -29,33 +31,63 @@ - (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
self.delegate = self;
- NSDate *date = [NSDate date];
gregorian = [NSCalendar currentCalendar];
- NSDateComponents *dateComponents = [gregorian components:(NSCalendarUnitMonth|NSCalendarUnitYear) fromDate:date];
- NSInteger currentMonth = [dateComponents month];
- NSInteger currentYear = [dateComponents year];
-
- years = [NSMutableArray array];
- for(NSInteger i = currentYear - DEFAULT_SIZE; i <= currentYear + DEFAULT_SIZE; i ++) {
- [years addObject: [NSNumber numberWithLong:i]];
- }
-
- months = [NSMutableArray array];
- NSDateFormatter *df = [[NSDateFormatter alloc] init];
- for(NSInteger i = 0; i < 12; i ++){
- [months addObject:[[df monthSymbols] objectAtIndex:(i)]];
- }
-
- selectedMonthRow = (DEFAULT_SIZE / 2) - 7 + currentMonth;
- selectedYearRow = DEFAULT_SIZE;
- [self selectRow:selectedMonthRow inComponent:0 animated:YES];
- [self selectRow:selectedYearRow inComponent:1 animated:YES];
+ _value = nil;
+ _minimumDate = nil;
+ _maximumDate = nil;
}
return self;
}
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
+- (void)initMonths {
+ months = [NSMutableArray array];
+ NSDateFormatter *df = [[NSDateFormatter alloc] init];
+ for(NSInteger i = 0; i < 12; i ++){
+ [months addObject:[[df monthSymbols] objectAtIndex:(i)]];
+ }
+}
+
+- (void)initYears:(NSInteger)selectedYear {
+ years = [NSMutableArray array];
+ for(NSInteger i = selectedYear - DEFAULT_SIZE; i <= selectedYear + DEFAULT_SIZE; i ++) {
+ [years addObject: [NSNumber numberWithLong:i]];
+ }
+}
+
+- (void)setValue:(nonnull NSDate *)value {
+ if (value != _value) {
+ NSDateComponents *selectedDateComponents = [gregorian components:(NSCalendarUnitMonth|NSCalendarUnitYear) fromDate:value];
+ if (!_value) {
+ [self initMonths];
+ [self initYears: [selectedDateComponents year]];
+
+ selectedMonthRow = [selectedDateComponents month] - 1;
+ selectedYearRow = DEFAULT_SIZE;
+ [self setSelectedRows: NO];
+ }
+ _value = value;
+ }
+}
+
+-(void)setSelectedRows:(BOOL)animated {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self selectRow:selectedMonthRow inComponent:0 animated:animated];
+ [self selectRow:selectedYearRow inComponent:1 animated:animated];
+ });
+}
+
+- (void)setMaximumDate:(NSDate *)maximumDate {
+ _maximumDate = maximumDate;
+ maxComponents = _maximumDate ? [gregorian components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:_maximumDate] : nil;
+}
+
+- (void)setMinimumDate:(NSDate *)minimumDate {
+ _minimumDate = minimumDate;
+ minComponents = _minimumDate ? [gregorian components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:_minimumDate] : nil;
+}
+
#pragma mark - UIPickerViewDataSource protocol
// number of columns
- (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView {
@@ -66,7 +98,7 @@ - (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView {
- (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
switch (component) {
case 0:
- return DEFAULT_SIZE;
+ return [months count];
case 1:
return [years count];
break;
@@ -80,7 +112,7 @@ - (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInCompone
- (NSString *)pickerView:(nonnull UIPickerView *) pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
switch (component) {
case 0:
- return [NSString stringWithFormat:@"%@", months[row % 12]];
+ return [NSString stringWithFormat:@"%@", months[row]];
case 1:
return [NSString stringWithFormat:@"%@", years[row]];
default:
@@ -88,39 +120,47 @@ - (NSString *)pickerView:(nonnull UIPickerView *) pickerView titleForRow:(NSInte
}
}
+- (void)getSelectedMonthRow:(NSInteger)row {
+ NSInteger month = row + 1;
+ NSInteger year = [years[selectedYearRow] longValue];
+ if (minComponents && year == [minComponents year] && month < [minComponents month]) {
+ selectedMonthRow = [minComponents month] - 1;
+ } else if (maxComponents && year == [maxComponents year] && month > [maxComponents month]) {
+ selectedMonthRow = [maxComponents month] - 1;
+ } else {
+ selectedMonthRow = row;
+ }
+}
+
+- (void)getSelectedYearRow:(NSInteger)row {
+ NSInteger year = [years[row] longValue];
+ if (minComponents && (year < [minComponents year])) {
+ selectedYearRow = [years indexOfObject:[NSNumber numberWithInteger:[minComponents year]]];
+ } else if (maxComponents && year > [maxComponents year]) {
+ selectedYearRow = [years indexOfObject:[NSNumber numberWithInteger:[maxComponents year]]];
+ } else {
+ selectedYearRow = row;
+ }
+}
+
- (void)pickerView:(__unused UIPickerView *)pickerView
didSelectRow:(NSInteger)row inComponent:(__unused NSInteger)component
{
- NSDateComponents *minComponents = _minimumDate ? [gregorian components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:_minimumDate] : nil;
- NSDateComponents *maxComponents = _maximumDate ? [gregorian components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:_maximumDate] : nil;
-
switch (component) {
- case 0: {
- NSInteger tmpMonth = (row % 12) + 1;
- NSInteger tmpYear = [years[selectedYearRow] longValue];
- if ((minComponents && tmpYear == [minComponents year] && tmpMonth < [minComponents month]) || (maxComponents && tmpYear == [maxComponents year] && tmpMonth > [maxComponents month])) {
- [self selectRow:selectedMonthRow inComponent:0 animated:true];
- return;
- }
- selectedMonthRow = row;
- break;td
- }
- case 1: {
- NSInteger tmpYear = [years[row] longValue];
- if ((minComponents && tmpYear < [minComponents year]) || (maxComponents && tmpYear > [maxComponents year])) {
- [self selectRow:selectedYearRow inComponent:1 animated:true];
- return;
- }
- selectedYearRow = row;
+ case 0:
+ [self getSelectedMonthRow:row];
+ break;
+ case 1:
+ [self getSelectedYearRow:row];
+ [self getSelectedMonthRow:selectedMonthRow];
break;
- }
default:
return;
}
-
+ [self setSelectedRows: YES];
if (_onChange) {
_onChange(@{
- @"newDate": [NSString stringWithFormat: @"%@-%@", [NSString stringWithFormat: @"%ld", (selectedMonthRow % 12) + 1], [NSString stringWithFormat: @"%@", years[selectedYearRow]]]
+ @"newDate": [NSString stringWithFormat: @"%@-%@", [NSString stringWithFormat: @"%ld", selectedMonthRow + 1], [NSString stringWithFormat: @"%@", years[selectedYearRow]]]
});
}
}
diff --git a/ios/RNMonthPickerManager.m b/ios/RNMonthPickerManager.m
index 40456c2..03d37cb 100644
--- a/ios/RNMonthPickerManager.m
+++ b/ios/RNMonthPickerManager.m
@@ -8,7 +8,7 @@
#import "RNMonthPickerManager.h"
#import "RNMonthPicker.h"
-
+
@implementation RNMonthPickerManager
RCT_EXPORT_MODULE()
diff --git a/package.json b/package.json
index 20c7f16..97f51a4 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
"readmeFilename": "README.md",
"peerDependencies": {
"react": "*",
- "react-native": ">=0.60.0-rc.0 <1.0.x"
+ "react-native": "*"
},
"devDependencies": {
"@react-native-community/eslint-config": "^1.1.0",
@@ -38,10 +38,11 @@
"conventional-changelog-eslint": "^3.0.4",
"eslint": "^6.8.0",
"react": "16.11.0",
- "react-native": "^0.62.2",
+ "react-native": "0.62.2",
"semantic-release": "^17.0.7"
},
"dependencies": {
+ "invariant": "^2.2.4",
"moment": "^2.24.0"
}
}
diff --git a/src/MonthPicker.ios.js b/src/MonthPicker.ios.js
index a9c7af4..21e6be9 100644
--- a/src/MonthPicker.ios.js
+++ b/src/MonthPicker.ios.js
@@ -1,6 +1,7 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import moment from 'moment';
+import invariant from 'invariant';
import RNMonthPickerView from './RNMonthPickerNativeComponent';
@@ -12,7 +13,12 @@ const styles = StyleSheet.create({
picker: { flex: 1 },
});
-const MonthPicker = ({ onChange, outputFormat, ...restProps }) => {
+const MonthPicker = ({ onChange, value, outputFormat, ...restProps }) => {
+ invariant(value, 'value prop is required!');
+
+ const getLongFromDate = (selectedValue) =>
+ moment(selectedValue, outputFormat || DEFAULT_OUTPUT_FORMAT).valueOf();
+
const onValueChange = (event) => {
const date = moment(event.nativeEvent.newDate, NATIVE_FORMAT).format(
outputFormat || DEFAULT_OUTPUT_FORMAT,
@@ -25,6 +31,7 @@ const MonthPicker = ({ onChange, outputFormat, ...restProps }) => {
diff --git a/yarn.lock b/yarn.lock
index a00e74f..6dc48c6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5451,7 +5451,12 @@ mime@1.6.0:
resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-mime@^2.4.1, mime@^2.4.3:
+mime@^2.4.1:
+ version "2.4.5"
+ resolved "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz#d8de2ecb92982dedbb6541c9b6841d7f218ea009"
+ integrity sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==
+
+mime@^2.4.3:
version "2.4.4"
resolved "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
@@ -5683,9 +5688,9 @@ node-modules-regexp@^1.0.0:
integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
node-stream-zip@^1.9.1:
- version "1.9.2"
- resolved "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.9.2.tgz#ef35da90a03627f275b3c7ead4cea1218f1f5a6a"
- integrity sha512-X9gnhFH8Egchv+CJwtiGYFtiRotf/gDL+MB3pV7KGFNbeYDo0NqAYocdQEU2czXj6npta9SbPj4bow1yQtoffA==
+ version "1.10.1"
+ resolved "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.10.1.tgz#d4c648e8d4cf97311e655b3c998d344ccbb421a8"
+ integrity sha512-fd2jdfvs3xJhSGpipy3EgCHGgFMXZkJh6HeQ8LURfMUW9oHcPEMWLXO657MtMRGJCHvQYQk6dTHZmNycu87PEg==
nopt@^4.0.1, nopt@~4.0.1:
version "4.0.3"
@@ -6727,7 +6732,7 @@ react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4:
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-react-native@^0.62.2:
+react-native@0.62.2:
version "0.62.2"
resolved "https://registry.npmjs.org/react-native/-/react-native-0.62.2.tgz#d831e11a3178705449142df19a70ac2ca16bad10"
integrity sha512-gADZZ3jcm2WFTjh8CCBCbl5wRSbdxqZGd+8UpNwLQFgrkp/uHorwAhLNqcd4+fHmADgPBltNL0uR1Vhv47zcOw==