1/** 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8#import "RNDateTimePickerManager.h" 9#import "RNDateTimePickerShadowView.h" 10 11#import <React/RCTBridge.h> 12#import <React/RCTEventDispatcher.h> 13#import "RNDateTimePicker.h" 14#import <React/UIView+React.h> 15 16#ifndef __IPHONE_15_0 17@interface UIColor (Xcode12) 18+ (instancetype) tintColor; 19@end 20#endif 21 22@implementation RCTConvert(UIDatePicker) 23 24RCT_ENUM_CONVERTER(UIDatePickerMode, (@{ 25 @"time": @(UIDatePickerModeTime), 26 @"date": @(UIDatePickerModeDate), 27 @"datetime": @(UIDatePickerModeDateAndTime), 28}), UIDatePickerModeTime, integerValue) 29 30 31#pragma clang diagnostic push 32#pragma clang diagnostic ignored "-Wunguarded-availability-new" 33#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 34 35typedef UIDatePickerStyle RNCUIDatePickerStyle; 36 37// using UIDatePickerStyle directly conflicts with RN implementation 38RCT_ENUM_CONVERTER(RNCUIDatePickerStyle, (@{ 39 @"default": @(UIDatePickerStyleAutomatic), 40 @"compact": @(UIDatePickerStyleCompact), 41 @"spinner": @(UIDatePickerStyleWheels), 42 @"inline": @(UIDatePickerStyleInline), 43}), UIDatePickerStyleAutomatic, integerValue) 44 45 46RCT_ENUM_CONVERTER(UIUserInterfaceStyle, (@{ 47 @"dark": @(UIUserInterfaceStyleDark), 48 @"light": @(UIUserInterfaceStyleLight), 49}), UIUserInterfaceStyleUnspecified, integerValue) 50 51#endif 52#pragma clang diagnostic pop 53 54 55@end 56 57@implementation RNDateTimePickerManager { 58 RNDateTimePicker* _picker; 59} 60 61RCT_EXPORT_MODULE() 62 63- (instancetype)init { 64 if (self = [super init]) { 65 _picker = [RNDateTimePicker new]; 66 } 67 return self; 68} 69 70+ (BOOL)requiresMainQueueSetup { 71 return true; 72} 73 74- (UIView *)view 75{ 76 return [RNDateTimePicker new]; 77} 78 79- (RCTShadowView *)shadowView 80{ 81 RNDateTimePickerShadowView* shadowView = [RNDateTimePickerShadowView new]; 82 shadowView.picker = _picker; 83 return shadowView; 84} 85 86+ (NSString*) datepickerStyleToString: (UIDatePickerStyle) style API_AVAILABLE(ios(13.4)){ 87 // RCTConvert does not handle this.? 88 switch (style) { 89 case UIDatePickerStyleCompact: 90 return @"compact"; 91 case UIDatePickerStyleWheels: 92 return @"spinner"; 93#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 94 case UIDatePickerStyleInline: 95 return @"inline"; 96#endif 97 default: 98 [NSException raise:@"Unsupported style value" format:@"UIDatePickerStyle of %ld is unsupported", (long)style]; 99 return @""; 100 } 101} 102 103RCT_EXPORT_SHADOW_PROPERTY(date, NSDate) 104RCT_EXPORT_SHADOW_PROPERTY(mode, UIDatePickerMode) 105RCT_EXPORT_SHADOW_PROPERTY(locale, NSLocale) 106RCT_EXPORT_SHADOW_PROPERTY(displayIOS, RNCUIDatePickerStyle) 107 108RCT_EXPORT_VIEW_PROPERTY(date, NSDate) 109RCT_EXPORT_VIEW_PROPERTY(locale, NSLocale) 110RCT_EXPORT_VIEW_PROPERTY(minimumDate, NSDate) 111RCT_EXPORT_VIEW_PROPERTY(maximumDate, NSDate) 112RCT_EXPORT_VIEW_PROPERTY(minuteInterval, NSInteger) 113RCT_EXPORT_VIEW_PROPERTY(enabled, BOOL) 114RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) 115RCT_EXPORT_VIEW_PROPERTY(onPickerDismiss, RCTBubblingEventBlock) 116 117RCT_REMAP_VIEW_PROPERTY(mode, datePickerMode, UIDatePickerMode) 118RCT_REMAP_VIEW_PROPERTY(timeZoneOffsetInMinutes, timeZone, NSTimeZone) 119 120RCT_CUSTOM_VIEW_PROPERTY(themeVariant, UIUserInterfaceStyle, RNDateTimePicker) { 121 if (@available(iOS 13.0, *)) { 122 if (json) { 123 UIUserInterfaceStyle propValue = [RCTConvert UIUserInterfaceStyle:json]; 124 view.overrideUserInterfaceStyle = propValue; 125 } else { 126 view.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified; 127 } 128 } 129} 130 131RCT_CUSTOM_VIEW_PROPERTY(textColor, UIColor, RNDateTimePicker) 132{ 133 if (@available(iOS 14.0, *)) { 134 if (view.datePickerStyle != UIDatePickerStyleWheels) { 135 // prevents #247 136 return; 137 } 138 } 139 if (json) { 140 [view setValue:[RCTConvert UIColor:json] forKey:@"textColor"]; 141 [view setValue:@(NO) forKey:@"highlightsToday"]; 142 } else { 143 UIColor* defaultColor; 144 if (@available(iOS 13.0, *)) { 145 defaultColor = [UIColor labelColor]; 146 } else { 147 defaultColor = [UIColor blackColor]; 148 } 149 [view setValue:defaultColor forKey:@"textColor"]; 150 [view setValue:@(YES) forKey:@"highlightsToday"]; 151 } 152} 153 154RCT_CUSTOM_VIEW_PROPERTY(accentColor, UIColor, RNDateTimePicker) 155{ 156 if (json) { 157 [view setTintColor:[RCTConvert UIColor:json]]; 158 } else { 159 if (@available(iOS 15.0, *)) { 160 [view setTintColor:[UIColor tintColor]]; 161 } else { 162 [view setTintColor:[UIColor systemBlueColor]]; 163 } 164 } 165} 166 167// TODO vonovak setting preferredDatePickerStyle invalidates minuteinterval 168RCT_CUSTOM_VIEW_PROPERTY(displayIOS, RNCUIDatePickerStyle, RNDateTimePicker) 169{ 170 // officially since 13.4 (https://developer.apple.com/documentation/uikit/uidatepickerstyle?language=objc) but practically since 14 171 if (@available(iOS 14.0, *)) { 172 if (json) { 173 UIDatePickerStyle propValue = [RCTConvert RNCUIDatePickerStyle:json]; 174 view.preferredDatePickerStyle = propValue; 175 } else { 176 view.preferredDatePickerStyle = UIDatePickerStyleAutomatic; 177 } 178 } 179} 180 181@end 182