Skip to content

Commit

Permalink
Initial changes
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsocj-cb committed Sep 15, 2022
1 parent 54a2efc commit 5b397d6
Show file tree
Hide file tree
Showing 15 changed files with 359 additions and 28 deletions.
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,30 @@ An existing Android emulator is required to match the name defined in `detox.con
yarn detox:android:build:release
yarn detox:android:test:release
```

### Fabric

Fabric is the new React Native rendering system ([read more about it here](https://reactnative.dev/architecture/fabric-renderer)).

#### iOS

```
yarn start
cd "example/ios" && RCT_NEW_ARCH_ENABLED=1 npx pod-install && cd -
yarn start:ios
```

If you want to go back to the old renderer (Paper),
remove `ios/build`, run `pod-install` without the `RCT_NEW_ARCH_ENABLED=1` and build again

```
rm -r "example/ios/build"
cd "example/ios" && npx pod-install && cd -
yarn start:ios
```


#### Android

The date time picker does not have a native UI component for Android but a native module.
([read more about native modules here](https://reactnative.dev/docs/native-modules-intro)).
26 changes: 24 additions & 2 deletions RNDateTimePicker.podspec
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'json'

fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'

package = JSON.parse(File.read(File.join(__dir__, 'package.json')))

Pod::Spec.new do |s|
Expand All @@ -12,8 +14,28 @@ Pod::Spec.new do |s|
s.homepage = package['homepage']
s.platform = :ios, "11.0"
s.source = { :git => "https://github.com/react-native-community/datetimepicker", :tag => "v#{s.version}" }
s.source_files = "ios/*.{h,m}"
s.source_files = "ios/**/*.{h,m,mm}"
s.requires_arc = true

s.dependency "React-Core"
if fabric_enabled
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'

s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
s.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/RCT-Folly"',
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
}

s.dependency "React"
s.dependency "React-RCTFabric"
s.dependency "React-Codegen"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
else
s.exclude_files = "ios/fabric"

s.dependency "React-Core"
end
end
2 changes: 1 addition & 1 deletion example/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Switch,
} from 'react-native';
import DateTimePicker from '@react-native-community/datetimepicker';
import SegmentedControl from '@react-native-segmented-control/segmented-control';
import SegmentedControl from './SegmentedControl';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import React, {useRef, useState} from 'react';
import {Picker} from 'react-native-windows';
Expand Down
7 changes: 7 additions & 0 deletions example/SegmentedControl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {isFabricEnabled} from '../src/utils';

import SegmentedControl from '@react-native-segmented-control/segmented-control';
import JSSegmentedControl from '@react-native-segmented-control/segmented-control/js/SegmentedControl.js';

// Forcing the JS implementation for Fabric as the native module is not compatible with Fabric yet.
export default isFabricEnabled ? JSSegmentedControl : SegmentedControl;
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ SPEC CHECKSUMS:
ReactCommon: de55f940495d7bf87b5d7bf55b5b15cdd50d7d7b
ReactTestApp-DevSupport: 8a8cff38c37cd8145a12ac7d7d0503dd08f97d65
ReactTestApp-Resources: ff5f151e465e890010b417ce65ca6c5de6aeccbb
RNDateTimePicker: 4f1fc917f5af9d9ae4c5fc0c63a4474d61338693
RNDateTimePicker: 9d66f002d6095cc89fcb66d0dc54bc6191c9ab0d
RNLocalize: cbcb55d0e19c78086ea4eea20e03fe8000bbbced
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
Yoga: 82c9e8f652789f67d98bed5aef9d6653f71b04a9
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
25 changes: 10 additions & 15 deletions ios/RNDateTimePicker.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
objectVersion = 46;
objects = {

/* Begin PBXBuildFile section */
1415EF09223110200027D3C6 /* RNDateTimePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1415EF07223110200027D3C6 /* RNDateTimePickerManager.m */; };
B3E7B58A1CC2AC0600A0062D /* RNDateTimePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNDateTimePicker.m */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
58B511D91A9E6C8500147676 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
Expand All @@ -25,10 +20,11 @@

/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNDateTimePicker.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNDateTimePicker.a; sourceTree = BUILT_PRODUCTS_DIR; };
1415EF07223110200027D3C6 /* RNDateTimePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNDateTimePickerManager.m; sourceTree = "<group>"; };
1415EF08223110200027D3C6 /* RNDateTimePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNDateTimePickerManager.h; sourceTree = "<group>"; };
B3E7B5881CC2AC0600A0062D /* RNDateTimePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNDateTimePicker.h; sourceTree = "<group>"; };
B3E7B5891CC2AC0600A0062D /* RNDateTimePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNDateTimePicker.m; sourceTree = "<group>"; };
7C1CCA3B28D0D66200DABF4D /* fabric */ = {isa = PBXFileReference; lastKnownFileType = folder; path = fabric; sourceTree = "<group>"; };
7C1CCA3D28D227F800DABF4D /* RNDateTimePicker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNDateTimePicker.m; sourceTree = "<group>"; };
7C1CCA3E28D227F800DABF4D /* RNDateTimePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNDateTimePicker.h; sourceTree = "<group>"; };
7C1CCA3F28D227F900DABF4D /* RNDateTimePickerManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNDateTimePickerManager.h; sourceTree = "<group>"; };
7C1CCA4028D227F900DABF4D /* RNDateTimePickerManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNDateTimePickerManager.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -53,10 +49,11 @@
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
1415EF08223110200027D3C6 /* RNDateTimePickerManager.h */,
1415EF07223110200027D3C6 /* RNDateTimePickerManager.m */,
B3E7B5881CC2AC0600A0062D /* RNDateTimePicker.h */,
B3E7B5891CC2AC0600A0062D /* RNDateTimePicker.m */,
7C1CCA3E28D227F800DABF4D /* RNDateTimePicker.h */,
7C1CCA3D28D227F800DABF4D /* RNDateTimePicker.m */,
7C1CCA3F28D227F900DABF4D /* RNDateTimePickerManager.h */,
7C1CCA4028D227F900DABF4D /* RNDateTimePickerManager.m */,
7C1CCA3B28D0D66200DABF4D /* fabric */,
134814211AA4EA7D00B7C361 /* Products */,
);
sourceTree = "<group>";
Expand Down Expand Up @@ -118,8 +115,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1415EF09223110200027D3C6 /* RNDateTimePickerManager.m in Sources */,
B3E7B58A1CC2AC0600A0062D /* RNDateTimePicker.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
9 changes: 9 additions & 0 deletions ios/fabric/RNDateTimePickerComponentView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import <React/RCTViewComponentView.h>

NS_ASSUME_NONNULL_BEGIN

@interface RNDateTimePickerComponentView : RCTViewComponentView

@end

NS_ASSUME_NONNULL_END
206 changes: 206 additions & 0 deletions ios/fabric/RNDateTimePickerComponentView.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#import "RNDateTimePickerComponentView.h"

#import <React/RCTConversions.h>

#import <react/renderer/components/RNDateTimePicker/ComponentDescriptors.h>
#import <react/renderer/components/RNDateTimePicker/EventEmitters.h>
#import <react/renderer/components/RNDateTimePicker/Props.h>
#import <react/renderer/components/RNDateTimePicker/RCTComponentViewHelpers.h>

#import "RCTFabricComponentsPlugins.h"
#import "RNDateTimePicker.h"

using namespace facebook::react;

@interface RNDateTimePickerComponentView () <RCTRNDateTimePickerViewProtocol>
@end

@implementation RNDateTimePickerComponentView {
UIDatePicker *_datePickerView;
}

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const RNDateTimePickerProps>();
_props = defaultProps;

_datePickerView = [[RNDateTimePicker alloc] initWithFrame:self.bounds];

[_datePickerView addTarget:self action:@selector(onChange:) forControlEvents:UIControlEventValueChanged];

// Default Picker mode
_datePickerView.datePickerMode = UIDatePickerModeDate;

self.contentView = _datePickerView;
}

return self;
}

-(void)onChange:(RNDateTimePicker *)sender
{
if (!_eventEmitter) {
return;
}

NSTimeInterval timestamp = [sender.date timeIntervalSince1970];
RNDateTimePickerEventEmitter::OnChange event = {
// Sending time in milliseconds
.timestamp = timestamp * 1000
};

std::dynamic_pointer_cast<const RNDateTimePickerEventEmitter>(_eventEmitter)
->onChange(event);
}

#pragma mark - RCTComponentViewProtocol

+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<RNDateTimePickerComponentDescriptor>();
}

// JS Standard for time is milliseconds
NSDate* convertJSTimeToDate (double jsTime) {
double time = jsTime/1000.0;
return [NSDate dateWithTimeIntervalSince1970: time];
}

-(void)updateTextColor:(UIColor *)color
{
if (@available(iOS 14.0, *)) {
if (_datePickerView.datePickerStyle != UIDatePickerStyleWheels) {
// prevents #247
return;
}
}

if (color == nil) {
// Default Text color
if (@available(iOS 13.0, *)) {
color = [UIColor labelColor];
} else {
color = [UIColor blackColor];
}
}

[_datePickerView setValue:color forKey:@"textColor"];
[_datePickerView setValue:@(NO) forKey:@"highlightsToday"];
}

- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &oldPickerProps = *std::static_pointer_cast<const RNDateTimePickerProps>(_props);
const auto &newPickerProps = *std::static_pointer_cast<const RNDateTimePickerProps>(props);

if (oldPickerProps.date != newPickerProps.date) {
_datePickerView.date = convertJSTimeToDate(newPickerProps.date);
}

if (oldPickerProps.minimumDate != newPickerProps.minimumDate) {
_datePickerView.minimumDate = convertJSTimeToDate(newPickerProps.minimumDate);
}

if (oldPickerProps.maximumDate != newPickerProps.maximumDate) {
_datePickerView.maximumDate = convertJSTimeToDate(newPickerProps.maximumDate);
}

if (oldPickerProps.locale != newPickerProps.locale) {
NSString *convertedLocale = RCTNSStringFromString(newPickerProps.locale);
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:convertedLocale];

_datePickerView.locale = locale;
}

if (oldPickerProps.mode != newPickerProps.mode) {
switch(newPickerProps.mode) {
case RNDateTimePickerMode::Time:
_datePickerView.datePickerMode = UIDatePickerModeTime;
break;
case RNDateTimePickerMode::Datetime:
_datePickerView.datePickerMode = UIDatePickerModeDateAndTime;
break;
case RNDateTimePickerMode::Countdown:
_datePickerView.datePickerMode = UIDatePickerModeCountDownTimer;
break;
default:
_datePickerView.datePickerMode = UIDatePickerModeDate;
}
}

if (@available(iOS 14.0, *)) {
if (oldPickerProps.displayIOS != newPickerProps.displayIOS) {
switch(newPickerProps.displayIOS) {
case RNDateTimePickerDisplayIOS::Compact:
_datePickerView.preferredDatePickerStyle = UIDatePickerStyleCompact;
break;
case RNDateTimePickerDisplayIOS::Inline:
_datePickerView.preferredDatePickerStyle = UIDatePickerStyleInline;
break;
case RNDateTimePickerDisplayIOS::Spinner:
_datePickerView.preferredDatePickerStyle = UIDatePickerStyleWheels;
break;
default:
_datePickerView.preferredDatePickerStyle = UIDatePickerStyleAutomatic;
}
}
}

if (oldPickerProps.minuteInterval != newPickerProps.minuteInterval) {
_datePickerView.minuteInterval = newPickerProps.minuteInterval;
}

if (oldPickerProps.timeZoneOffsetInMinutes != newPickerProps.timeZoneOffsetInMinutes) {
// JS standard for time zones is minutes.
_datePickerView.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:newPickerProps.timeZoneOffsetInMinutes * 60.0];
}

if (oldPickerProps.accentColor != newPickerProps.accentColor) {
UIColor *color = RCTUIColorFromSharedColor(newPickerProps.accentColor);

if (color != nil) {
[_datePickerView setTintColor:color];
} else {
if (@available(iOS 15.0, *)) {
[_datePickerView setTintColor:[UIColor tintColor]];
} else {
[_datePickerView setTintColor:[UIColor systemBlueColor]];
}
}
}

if (oldPickerProps.textColor != newPickerProps.textColor) {
[self updateTextColor:RCTUIColorFromSharedColor(newPickerProps.textColor)];
}

if (@available(iOS 13.0, *)) {
if (oldPickerProps.themeVariant != newPickerProps.themeVariant) {
switch (newPickerProps.themeVariant) {
case RNDateTimePickerThemeVariant::Light:
_datePickerView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
break;
case RNDateTimePickerThemeVariant::Dark:
_datePickerView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
break;
default:
_datePickerView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
}
}
}

if (oldPickerProps.enabled != newPickerProps.enabled) {
_datePickerView.enabled = newPickerProps.enabled;
}


[super updateProps:props oldProps:oldProps];
}

@end

Class<RCTComponentViewProtocol> RNDateTimePickerCls(void)
{
return RNDateTimePickerComponentView.class;
}

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,10 @@
}
}
}
},
"codegenConfig": {
"name": "RNDateTimePicker",
"type": "components",
"jsSrcsDir": "src/specs"
}
}
Loading

0 comments on commit 5b397d6

Please sign in to comment.