diff --git a/README.md b/README.md
index 13de8fdc..57423265 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
This is a React Native Date Picker with following main features:
📱 Supports iOS, Android and Expo
-🕑 3 different modes: Time, Date, DateTime
+🕑 4 different modes: Time, Date, DateTime, YearAndMonth
🌍 Various languages
🎨 Customizable
🖼 Modal or Inlined
@@ -181,7 +181,7 @@ export default () => {
| `maximumDate` | Maximum selectable date.
Example: `new Date("2021-12-31")` |
| `minimumDate` | Minimum selectable date.
Example: `new Date("2021-01-01")` |
| `minuteInterval` | The interval at which minutes can be selected. |
|
|
-| `mode` | The date picker mode. `"datetime"`, `"date"`, `"time"` | 

| 

|
+| `mode` | The date picker mode. `"datetime"`, `"date"`, `"time"`, `"yearAndMonth"` | 

| 

|
| `locale` | The locale for the date picker. Changes language, date order and am/pm preferences. Value needs to be a Locale ID. |
|
|
| `timeZoneOffsetInMinutes` | Timezone offset in minutes (default: device's timezone) |
| `is24hourSource` | Change how the 24h mode (am/pm) should be determined, by device settings or by locale. {'locale', 'device'} (android only, default: 'device') |
@@ -227,7 +227,7 @@ On iOS the 12/24h preference is determined by the `locale` prop. Set for instanc
### Is it possible to show only month and year?
-This is unfortunately not possible due to the limitation in DatePickerIOS. You should be able to create your own month-year picker with for instance https://github.com/TronNatthakorn/react-native-wheel-pick.
+Yes! You can use the `"yearAndMonth"` mode which displays only month and year selection on both platforms.
### Why does the Android app crash in production?
@@ -253,9 +253,9 @@ const [state, setState] = useState("idle")
```
-## Three different modes
+## Different picker modes
-Here are some more info about the three different picker modes that are available.
+Here are some more info about the different picker modes that are available.
### Date time picker
@@ -320,6 +320,23 @@ Set mode property to `time` to show the time picker:
/>
```
+### Month Year picker
+
+The yearAndMonth mode allows you to select only month and year, which is useful for selecting birth months, credit card expiration dates, or other month/year selections. This mode uses the native `UIDatePickerModeYearAndMonth`.
+
+Set mode property to `yearAndMonth` to show the month year picker:
+
+```jsx
+
+```
+
+**Compatibility Notes:**
+- **iOS**: Displays the native year and month picker (`UIDatePickerModeYearAndMonth`)
+- **Android**: Displays year and month wheels (without the date wheel)
+
## About
React Native Date Picker is a cross platform component for iOS and Android. It uses native code from respective platform to get the genuine look and feel the users expect. A strong motivation for creating this picker was the datetime mode on Android. It's quite unique for the platform and avoids two different picker popups, which normally is necessary. Instead, this datetime mode requires fewer user actions and enables a great user-experience.
diff --git a/android/src/main/java/com/henninghall/date_picker/DerivedData.java b/android/src/main/java/com/henninghall/date_picker/DerivedData.java
index 9612238e..68968f58 100644
--- a/android/src/main/java/com/henninghall/date_picker/DerivedData.java
+++ b/android/src/main/java/com/henninghall/date_picker/DerivedData.java
@@ -39,6 +39,11 @@ public ArrayList getVisibleWheels() {
visibleWheels.add(WheelType.DATE);
break;
}
+ case yearAndMonth: {
+ visibleWheels.add(WheelType.YEAR);
+ visibleWheels.add(WheelType.MONTH);
+ break;
+ }
}
if((mode == Mode.time || mode == Mode.datetime) && state.derived.usesAmPm()){
visibleWheels.add(WheelType.AM_PM);
diff --git a/android/src/main/java/com/henninghall/date_picker/models/Mode.java b/android/src/main/java/com/henninghall/date_picker/models/Mode.java
index 041b6fa0..c438372f 100644
--- a/android/src/main/java/com/henninghall/date_picker/models/Mode.java
+++ b/android/src/main/java/com/henninghall/date_picker/models/Mode.java
@@ -1,5 +1,5 @@
package com.henninghall.date_picker.models;
public enum Mode {
- date, time, datetime
+ date, time, datetime, yearAndMonth
}
diff --git a/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java b/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java
index a65399b2..e3abc2a2 100644
--- a/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java
+++ b/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java
@@ -100,10 +100,24 @@ private String getDateModeString(int daysToSubtract) {
return sb.toString();
}
+ private String getYearAndMonthString(int daysToSubtract) {
+ ArrayList wheels = getOrderedVisibleWheels();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 2; i++) {
+ if (i != 0) sb.append(" ");
+ Wheel w = wheels.get(i);
+ sb.append(w.getValue());
+ }
+ return sb.toString();
+ }
+
private String getDateString(int daysToSubtract){
if(state.getMode() == Mode.date ){
return getDateModeString(daysToSubtract);
}
+ if(state.getMode() == Mode.yearAndMonth ){
+ return getYearAndMonthString(daysToSubtract);
+ }
return dayWheel.getValue();
}
@@ -170,6 +184,10 @@ private String getDateFormatPattern(){
+ wheels.get(1).getFormatPattern() + " "
+ wheels.get(2).getFormatPattern();
}
+ if(state.getMode() == Mode.yearAndMonth){
+ return wheels.get(0).getFormatPattern() + " "
+ + wheels.get(1).getFormatPattern();
+ }
return dayWheel.getFormatPattern();
}
diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java
index 4724d957..a183269c 100644
--- a/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java
+++ b/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java
@@ -43,7 +43,7 @@ public String toDisplayValue(String value) {
@Override
public boolean visible() {
- return state.getMode() != Mode.date;
+ return state.getMode() != Mode.date && state.getMode() != Mode.yearAndMonth;
}
@Override
diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java
index 8afa3fc1..9446060a 100644
--- a/android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java
+++ b/android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java
@@ -32,7 +32,7 @@ public ArrayList getValues() {
@Override
public boolean visible() {
- return state.getMode() != Mode.date;
+ return state.getMode() != Mode.date && state.getMode() != Mode.yearAndMonth;
}
@Override
diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java
index 4eb3a500..6c0c60d0 100644
--- a/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java
+++ b/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java
@@ -28,7 +28,7 @@ public ArrayList getValues() {
@Override
public boolean visible() {
- return state.getMode() == Mode.date;
+ return state.getMode() == Mode.date || state.getMode() == Mode.yearAndMonth;
}
@Override
diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java
index 41e0427a..fb45ffb8 100644
--- a/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java
+++ b/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java
@@ -56,7 +56,7 @@ private int getStartYear() {
@Override
public boolean visible() {
- return state.getMode() == Mode.date;
+ return state.getMode() == Mode.date || state.getMode() == Mode.yearAndMonth;
}
@Override
diff --git a/index.d.ts b/index.d.ts
index 0ab796f6..761495cf 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -34,7 +34,7 @@ export interface DatePickerProps extends ViewProps {
/**
* The date picker mode.
*/
- mode?: 'date' | 'time' | 'datetime'
+ mode?: 'date' | 'time' | 'datetime' | 'yearAndMonth'
/**
* Date change handler.
diff --git a/ios/RNDatePicker.mm b/ios/RNDatePicker.mm
index 7ec2dd20..fd9ce2e8 100644
--- a/ios/RNDatePicker.mm
+++ b/ios/RNDatePicker.mm
@@ -135,6 +135,13 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
if(newViewProps.mode == RNDatePickerMode::Time) [_picker setDatePickerMode:UIDatePickerModeTime];
if(newViewProps.mode == RNDatePickerMode::Date) [_picker setDatePickerMode:UIDatePickerModeDate];
if(newViewProps.mode == RNDatePickerMode::Datetime) [_picker setDatePickerMode:UIDatePickerModeDateAndTime];
+ if(newViewProps.mode == RNDatePickerMode::YearAndMonth) {
+ if (@available(iOS 17.4, *)) {
+ [_picker setDatePickerMode:UIDatePickerModeYearAndMonth];
+ } else {
+ [_picker setDatePickerMode:(UIDatePickerMode)4269]; // magic number from iOS team
+ }
+ }
// We need to set minuteInterval after setting datePickerMode, otherwise minuteInterval is invalid in time mode.
_picker.minuteInterval = _reactMinuteInterval;
}
diff --git a/ios/RNDatePickerManager.mm b/ios/RNDatePickerManager.mm
index da42873c..6773a020 100644
--- a/ios/RNDatePickerManager.mm
+++ b/ios/RNDatePickerManager.mm
@@ -9,12 +9,29 @@
@implementation RCTConvert(UIDatePicker)
-RCT_ENUM_CONVERTER(UIDatePickerMode, (@{
- @"time": @(UIDatePickerModeTime),
- @"date": @(UIDatePickerModeDate),
- @"datetime": @(UIDatePickerModeDateAndTime),
- @"countdown": @(UIDatePickerModeCountDownTimer), // not supported yet
-}), UIDatePickerModeTime, integerValue)
++ (UIDatePickerMode)UIDatePickerMode:(id)json
+{
+ static NSDictionary *modes;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ modes = @{
+ @"time": @(UIDatePickerModeTime),
+ @"date": @(UIDatePickerModeDate),
+ @"datetime": @(UIDatePickerModeDateAndTime),
+ @"countdown": @(UIDatePickerModeCountDownTimer), // not supported yet
+ };
+ });
+
+ if ([json isEqualToString:@"yearAndMonth"]) {
+ if (@available(iOS 17.4, *)) {
+ return (UIDatePickerModeYearAndMonth);
+ } else {
+ return (UIDatePickerMode)4269;
+ }
+ }
+
+ return (UIDatePickerMode)[RCTConvertEnumValue("UIDatePickerMode", modes, @(UIDatePickerModeTime), json) integerValue];
+}
@end
diff --git a/npmREADME.md b/npmREADME.md
index 374261bb..e899a0bb 100644
--- a/npmREADME.md
+++ b/npmREADME.md
@@ -1,6 +1,6 @@
# React Native Date Picker
-A cross platform react native date picker component for android and ios. It includes 3 different modes: date, time, and datetime. The date picker is customizable and has multiple language support.
+A cross platform react native date picker component for android and ios. It includes 4 different modes: date, time, datetime, and yearAndMonth. The date picker is customizable and has multiple language support.
## Modal
diff --git a/package.json b/package.json
index 469386dc..36460e4e 100644
--- a/package.json
+++ b/package.json
@@ -70,9 +70,6 @@
"ios": {
"componentProvider": {
"RNDatePicker": "RNDatePicker"
- },
- "modulesProvider": {
- "RNDatePicker": "RNDatePickerManager"
}
}
}
diff --git a/src/DatePickerIOS.js b/src/DatePickerIOS.js
index 987cbcac..268519bc 100644
--- a/src/DatePickerIOS.js
+++ b/src/DatePickerIOS.js
@@ -23,8 +23,12 @@ export const DatePickerIOS = (props) => {
style: [styles.datePickerIOS, props.style],
date: props.date ? props.date.toISOString() : undefined,
locale: props.locale ? props.locale : undefined,
- maximumDate: props.maximumDate ? props.maximumDate.toISOString() : undefined,
- minimumDate: props.minimumDate ? props.minimumDate.toISOString() : undefined,
+ maximumDate: props.maximumDate
+ ? props.maximumDate.toISOString()
+ : undefined,
+ minimumDate: props.minimumDate
+ ? props.minimumDate.toISOString()
+ : undefined,
theme: props.theme ? props.theme : 'auto',
}
diff --git a/src/propChecker.js b/src/propChecker.js
index e2723f86..cc736eb5 100644
--- a/src/propChecker.js
+++ b/src/propChecker.js
@@ -53,7 +53,9 @@ const heightCheck = new PropCheck(
const modeCheck = new PropCheck(
(props) =>
- props && props.mode && !['datetime', 'date', 'time'].includes(props.mode),
+ props &&
+ props.mode &&
+ !['datetime', 'date', 'time', 'yearAndMonth'].includes(props.mode),
"Invalid mode. Valid modes: 'datetime', 'date', 'time'"
)