diff --git a/CHANGELOG.md b/CHANGELOG.md
index b088ba4799b03b80843950977beb6ddd6e1829fc..4591f22ade465a11cf69cb5b6b174af11fb6f5af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,102 +1,2 @@
# CHANGELOG
-### Changelog is no longer maintained
-
-Please see the [releases page](https://github.com/react-native-community/datetimepicker/releases)
-
-### 2.6.0
-
-- Add time picker for Windows [#206](https://github.com/react-native-community/datetimepicker/pull/206)
-
-### 2.5.0
-
-- feat: add minute interval on Android [#177](https://github.com/react-native-community/datetimepicker/pull/177)
-
-### 2.4.3
-
-- Fix TS typings [#197](https://github.com/react-native-community/datetimepicker/pull/197)
-- document working with dark mode [#204](https://github.com/react-native-community/datetimepicker/pull/204)
-
-### 2.4.2
-
-- Make react-native-windows optional [#191](https://github.com/react-native-community/datetimepicker/pull/191)
-
-### 2.4.1
-
-- allow compiling with xcode 10 [#186](https://github.com/react-native-community/datetimepicker/pull/186)
-
-### 2.4.0
-
-- Add Windows date picker [#157](https://github.com/react-native-community/datetimepicker/pull/157)
-- Update Example App to RN 0.62.2 [#146](https://github.com/react-native-community/datetimepicker/pull/146)
-- throw when invalid props are passed to android picker [#148](https://github.com/react-native-community/datetimepicker/pull/148)
-- Recommend npx pod-install for setup instructions [#159](https://github.com/react-native-community/datetimepicker/pull/159)
-
-### 2.3.2
-
-- Fix android nougat display spinner [#118](https://github.com/react-native-community/datetimepicker/pull/118)
-
-### 2.3.1
-
-- fix typescript compilation errors #138, #143
-- use yarn for managing deps (this should not influence consumers)
-
-### 2.3.0
-
-- add `textColor` prop for iOS: [#127](https://github.com/react-native-community/datetimepicker/pull/127)
-
-### 2.2.3
-
-- Fix iOS picker's styling bug where picker would be fixed to 216px height no matter what `style` was applied to the picker. This is because previously, the picker was always wrapped in a `View` which was now removed. Since `style` prop was never documented in this package, we do not consider this a breaking change. Now `style` can correctly apply specific height settings and flex. NOTE: this only works with View style property type. [#120](https://github.com/react-native-community/react-native-datetimepicker/pull/120)
-- update readme example code [#124](https://github.com/react-native-community/react-native-datetimepicker/pull/124)
-
-### 2.2.2
-
-- Fix android time picker returning today's date instead of the given date [#115](https://github.com/react-native-community/react-native-datetimepicker/pull/115)
-
-### 2.2.1
-
-- Fix missing return statement [#107](https://github.com/react-native-community/react-native-datetimepicker/pull/107)
-
-### 2.2.0
-
-- Fix podspec to get source from tag [#103](https://github.com/react-native-community/react-native-datetimepicker/pull/103)
-- fix prettier usage [#102](https://github.com/react-native-community/react-native-datetimepicker/pull/102)
-- Introduce neutral button via neutralButtonLabel on Android pickers [#93](https://github.com/react-native-community/react-native-datetimepicker/pull/93)
-- update readme [#100](https://github.com/react-native-community/react-native-datetimepicker/pull/100)
-
-### 2.1.2
-
-- Fix Android Nougat datetime picker mode="spinner" [#47](https://github.com/react-native-community/react-native-datetimepicker/pull/47)
-
-### 2.1.1
-
-- Add `countdown` option to iOSMode types [#31](https://github.com/react-native-community/react-native-datetimepicker/pull/31)
-- Added TS type definition file path to package.json [#77](https://github.com/react-native-community/react-native-datetimepicker/pull/77)
-- Improved readme [#33](https://github.com/react-native-community/react-native-datetimepicker/pull/33), [#39](https://github.com/react-native-community/react-native-datetimepicker/pull/39), [#46](https://github.com/react-native-community/react-native-datetimepicker/pull/46), [#97](https://github.com/react-native-community/react-native-datetimepicker/pull/97)
-
-### 2.1.0
-
-- [#25] Add typescript definitions.
-- [#22] Fix backtick in documentation.
-
-### 2.0.0
-
-- [#13] Update to `react-native@0.60`
-
-### 1.0.0
-
-- [#7] Adding Readme.md and docs
-- [#6] Detox tests added
-- [#5] Adjust CHANGELOG.md to have links at bottom of markdown
-- [#4] Fixing iOS React import and cleaning iOS example project
-- [#3] Using @react-native-community/eslint-config
-
-[#3]: https://github.com/react-native-community/react-native-datetimepicker/pull/3
-[#4]: https://github.com/react-native-community/react-native-datetimepicker/pull/4
-[#5]: https://github.com/react-native-community/react-native-datetimepicker/pull/5
-[#6]: https://github.com/react-native-community/react-native-datetimepicker/pull/6
-[#7]: https://github.com/react-native-community/react-native-datetimepicker/pull/7
-[#13]: https://github.com/react-native-community/react-native-datetimepicker/pull/13
-[#22]: https://github.com/react-native-community/react-native-datetimepicker/pull/22
-[#25]: https://github.com/react-native-community/react-native-datetimepicker/pull/25
diff --git a/COMMITTERS.md b/COMMITTERS.md
new file mode 100644
index 0000000000000000000000000000000000000000..2f2ff6acab1e0c6e261014bf8ae6c537e7e9e533
--- /dev/null
+++ b/COMMITTERS.md
@@ -0,0 +1,10 @@
+## Committers列表
+
+### 以下是此项目的committer人员
+不区分先后顺序
+
+- [MaDiXin](https://gitee.com/MaDiXin)
+- [xiafeng_xf_admin](https://gitee.com/xiafeng_xf_admin)
+- [ChenLixi](https://gitee.com/Louis-C7)
+- [LinJiacheng](https://gitee.com/LLLLLLin)
+- [ZhengJinshou](https://gitee.com/longziz)
\ No newline at end of file
diff --git a/README.OpenSource b/README.OpenSource
new file mode 100644
index 0000000000000000000000000000000000000000..144f5e9f41caf13eac6cc451ed8fcecbf8a93877
--- /dev/null
+++ b/README.OpenSource
@@ -0,0 +1,11 @@
+[
+ {
+ "Name": "@react-native-community/datetimepicker",
+ "License": "MIT License",
+ "License File": "https://github.com/react-native-datetimepicker/datetimepicker/blob/master/LICENSE.md",
+ "Version Number": "7.6.2",
+ "Owner" : "xiafeng@huawei.com",
+ "Upstream URL": "https://github.com/react-native-datetimepicker/datetimepicker",
+ "Description": "DateTimePicker component for React Native"
+ }
+]
\ No newline at end of file
diff --git a/example/.eslintrc b/example/.eslintrc
new file mode 100644
index 0000000000000000000000000000000000000000..76cd1cdca17f5f45ea5a75fd4b493c47655cbe67
--- /dev/null
+++ b/example/.eslintrc
@@ -0,0 +1,13 @@
+{
+ "extends": "@react-native",
+ "rules": {
+ "react-native/no-inline-styles": "off",
+ "react/no-unstable-nested-components": "off",
+ "react/react-in-jsx-scope": "off",
+ "@typescript-eslint/no-unused-vars": "warn",
+ "react-hooks/exhaustive-deps": "off",
+ "radix": "off",
+ "prettier/prettier": "warn",
+ "max-lines": "off"
+ }
+}
\ No newline at end of file
diff --git a/example/.gitignore b/example/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..7613cdedd309866629ce9ae75eb3855ea0849f0a
--- /dev/null
+++ b/example/.gitignore
@@ -0,0 +1,71 @@
+.husky
+bundle.harmony.js
+package-lock.json
+*.hbc
+lintCppResult.txt
+
+# ---
+
+# OSX
+#
+.DS_Store
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+
+# Android/IntelliJ
+#
+build/
+.idea
+.gradle
+local.properties
+*.iml
+*.hprof
+.cxx/
+*.keystore
+!debug.keystore
+BuildProfile.ets
+
+# node.js
+#
+node_modules/
+npm-debug.log
+yarn-error.log
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
+# screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/
+
+**/fastlane/report.xml
+**/fastlane/Preview.html
+**/fastlane/screenshots
+**/fastlane/test_output
+
+# Bundle artifact
+*.jsbundle
+
+# Ruby / CocoaPods
+/vendor/bundle/
+
+# Temporary files created by Metro to check the health of the file watcher
+.metro-health-check*
+*.htrace
\ No newline at end of file
diff --git a/example/.node-version b/example/.node-version
new file mode 100644
index 0000000000000000000000000000000000000000..3c032078a4a21c5c51d3c93d91717c1dabbb8cd0
--- /dev/null
+++ b/example/.node-version
@@ -0,0 +1 @@
+18
diff --git a/example/.prettierrc.js b/example/.prettierrc.js
new file mode 100644
index 0000000000000000000000000000000000000000..2ae7b381ed9590ddf3ba512a496dc8d53dadeea0
--- /dev/null
+++ b/example/.prettierrc.js
@@ -0,0 +1,7 @@
+module.exports = {
+ arrowParens: 'avoid',
+ bracketSameLine: true,
+ bracketSpacing: true,
+ singleQuote: true,
+ trailingComma: 'all',
+};
diff --git a/example/.watchmanconfig b/example/.watchmanconfig
new file mode 100644
index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b
--- /dev/null
+++ b/example/.watchmanconfig
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/example/app.json b/example/app.json
new file mode 100644
index 0000000000000000000000000000000000000000..7586f6fa99a6680a35a27fac7255ba721880d461
--- /dev/null
+++ b/example/app.json
@@ -0,0 +1,4 @@
+{
+ "name": "app_name",
+ "displayName": "tester"
+}
\ No newline at end of file
diff --git a/example/babel.config.js b/example/babel.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..481136144aa7bed704ad81628802d8a43930a6a1
--- /dev/null
+++ b/example/babel.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ presets: ['module:metro-react-native-babel-preset'],
+ plugins: [
+ ],
+};
diff --git a/example/contexts.ts b/example/contexts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9437598452691ccc56d19f5532607475aa5d33b4
--- /dev/null
+++ b/example/contexts.ts
@@ -0,0 +1,3 @@
+import React from 'react';
+
+export const AppParamsContext = React.createContext(undefined);
diff --git a/example/harmony/.gitignore b/example/harmony/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..72d73fb4b6240ccd907882c931ce08ee45ca62ba
--- /dev/null
+++ b/example/harmony/.gitignore
@@ -0,0 +1,24 @@
+# it may cause some issues when building the project when switching branches
+package-lock.json
+# we add this because we want to keep the signing configs out of git
+/build-profile.json5
+
+rnoh_modules
+
+**/oh-package-lock.json5
+# ---
+
+/node_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+/oh_modules
+hvigorw
+hvigorw.bat
+hvigor/hvigor-wrapper.js
+
diff --git a/example/harmony/AppScope/app.json5 b/example/harmony/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..058bd391dac60928a1857aa31e4b0f712a7bc743
--- /dev/null
+++ b/example/harmony/AppScope/app.json5
@@ -0,0 +1,10 @@
+{
+ "app": {
+ "bundleName": "com.harmony.wechat.lib.demo",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/example/harmony/AppScope/resources/base/element/string.json b/example/harmony/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..698a720065342ae0dadad63eb87d45fec8725f36
--- /dev/null
+++ b/example/harmony/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "RN Tester"
+ }
+ ]
+}
diff --git a/example/harmony/AppScope/resources/base/media/app_icon.png b/example/harmony/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/example/harmony/AppScope/resources/base/media/app_icon.png differ
diff --git a/example/harmony/build-profile.template.json5 b/example/harmony/build-profile.template.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7057b6913662f96b37b03ecc7a7573168d319421
--- /dev/null
+++ b/example/harmony/build-profile.template.json5
@@ -0,0 +1,40 @@
+{
+ "app": {
+ "products": [
+ {
+ "name": 'default',
+ "signingConfig": 'default',
+ "compileSdkVersion": '5.0.1(13)',
+ "compatibleSdkVersion": '5.0.0(12)',
+ "runtimeOS": 'HarmonyOS'
+ },
+ ],
+ "buildModeSet": [
+ {
+ "name": 'debug',
+ },
+ {
+ "name": 'release',
+ },
+ ],
+ "signingConfigs": []
+ },
+ "modules": [
+ {
+ "name": 'entry',
+ "srcPath": './entry',
+ "targets": [
+ {
+ "name": 'default',
+ "applyToProducts": [
+ 'default'
+ ],
+ },
+ ],
+ },
+ {
+ "name": "image_crop_picker",
+ "srcPath": '../../harmony/image_crop_picker'
+ }
+ ],
+}
\ No newline at end of file
diff --git a/example/harmony/codelinter.json b/example/harmony/codelinter.json
new file mode 100644
index 0000000000000000000000000000000000000000..e7f91acb037aeda939967a042f16033f4c6e21b9
--- /dev/null
+++ b/example/harmony/codelinter.json
@@ -0,0 +1,32 @@
+{
+ "files": ["**/*.ts", "**/*.ets"],
+ "ignore": [
+ "**/ohosTest/**/*",
+ "**/node_modules/**/*",
+ "**/hvigorfile.ts",
+ "**/node_modules/**/*",
+ "**/oh_modules/**/*",
+ "**/build/**/*",
+ "**/.preview/**/*"
+ ],
+ "plugins": ["@typescript-eslint"],
+ "ruleSet": [],
+ "rules": {
+ "@typescript-eslint/await-thenable": "warn",
+ "@typescript-eslint/consistent-type-imports": "warn",
+ "@typescript-eslint/explicit-function-return-type": "warn",
+ "@typescript-eslint/explicit-module-boundary-types": "warn",
+ "@typescript-eslint/no-dynamic-delete": "warn",
+ "@typescript-eslint/no-explicit-any": "warn",
+ "@typescript-eslint/no-for-in-array": "warn",
+ "@typescript-eslint/no-this-alias": "warn",
+ "@typescript-eslint/no-unnecessary-type-constraint": "warn",
+ "@typescript-eslint/no-unsafe-argument": "warn",
+ "@typescript-eslint/no-unsafe-assignment": "warn",
+ "@typescript-eslint/no-unsafe-call": "warn",
+ "@typescript-eslint/no-unsafe-member-access": "warn",
+ "@typescript-eslint/no-unsafe-return": "warn",
+ "@typescript-eslint/prefer-literal-enum-member": "warn"
+ },
+ "overrides": []
+}
diff --git a/example/harmony/entry/.gitignore b/example/harmony/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..bbc049cfeb689c61d6c2922810f652cbb19aad21
--- /dev/null
+++ b/example/harmony/entry/.gitignore
@@ -0,0 +1,7 @@
+/node_modules
+/.preview
+/build
+/.cxx
+package-lock.json
+/oh_modules
+/assets
diff --git a/example/harmony/entry/build-profile.json5 b/example/harmony/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..2408c163287e825139a36f35cbec83e9772c49db
--- /dev/null
+++ b/example/harmony/entry/build-profile.json5
@@ -0,0 +1,19 @@
+{
+ "apiType": 'stageMode',
+ "buildOption": {
+ "externalNativeOptions": {
+ "path": "./src/main/cpp/CMakeLists.txt",
+ "arguments": "",
+ "cppFlags": "-s",
+ },
+ },
+ "targets": [
+ {
+ "name": "default",
+ "runtimeOS": "HarmonyOS"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/harmony/entry/hvigorfile.ts b/example/harmony/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aced8afddf910b99762b7eff3a8df92cb9f30c2b
--- /dev/null
+++ b/example/harmony/entry/hvigorfile.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { hapTasks } from '@ohos/hvigor-ohos-plugin';
diff --git a/example/harmony/entry/oh-package.json5 b/example/harmony/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..0b00b3d2604eb63560099414c2979039b5e83194
--- /dev/null
+++ b/example/harmony/entry/oh-package.json5
@@ -0,0 +1,11 @@
+{
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "entry",
+ "description": "example description",
+ "version": "1.0.0",
+ "dependencies": {
+ "@rnoh/react-native-openharmony": "^0.72.38",
+ "@react-native-ohos/datetimepicker": "../../../harmony/datetimepicker"
+ }
+}
\ No newline at end of file
diff --git a/example/harmony/entry/src/main/cpp/.gitignore b/example/harmony/entry/src/main/cpp/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..881dde5479f322de9db2b2bb98fd94a95f73715e
--- /dev/null
+++ b/example/harmony/entry/src/main/cpp/.gitignore
@@ -0,0 +1,2 @@
+jsbundle.h
+generated/
diff --git a/example/harmony/entry/src/main/cpp/CMakeLists.txt b/example/harmony/entry/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c0a10d092d6a159ca303a502f5f35263fa659026
--- /dev/null
+++ b/example/harmony/entry/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,35 @@
+project(rnapp)
+cmake_minimum_required(VERSION 3.4.1)
+set(CMAKE_SKIP_BUILD_RPATH TRUE)
+set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules/@rnoh/react-native-openharmony/src/main/cpp")
+set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
+set(LOG_VERBOSITY_LEVEL 1)
+set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
+set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
+set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+
+set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
+add_compile_definitions(WITH_HITRACE_SYSTRACE)
+
+add_subdirectory("${RNOH_CPP_DIR}" ./rn)
+
+# RNOH_BEGIN: manual_package_linking_1
+add_subdirectory("${OH_MODULES}/@react-native-oh-tpl/datetimepicker/src/main/cpp" ./datetimepicker)
+# RNOH_END: manual_package_linking_1
+
+file(GLOB GENERATED_CPP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/generated/*.cpp") # this line is needed by codegen v1
+
+add_library(rnoh_app SHARED
+ ${GENERATED_CPP_FILES}
+ ${IMAGE_CROP_PICKER_CPP_FILES}
+ "./PackageProvider.cpp"
+ "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
+)
+target_link_libraries(rnoh_app PUBLIC rnoh)
+
+# RNOH_BEGIN: manual_package_linking_2
+target_link_libraries(rnoh_app PUBLIC rnoh_datetime_picker)
+# RNOH_END: manual_package_linking_2
diff --git a/example/harmony/entry/src/main/cpp/PackageProvider.cpp b/example/harmony/entry/src/main/cpp/PackageProvider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..910f577c9c01ad3c7562b9fadcbe52924f8da8f4
--- /dev/null
+++ b/example/harmony/entry/src/main/cpp/PackageProvider.cpp
@@ -0,0 +1,21 @@
+/*
+*
+* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+* Use of this source code is governed by a MIT license that can be
+* found in the LICENSE file
+*
+*/
+
+#include "RNOH/PackageProvider.h"
+#include "generated/RNOHGeneratedPackage.h"
+#include "DateTimePickerPackage.h"
+
+using namespace rnoh;
+
+std::vector> PackageProvider::getPackages(Package::Context ctx)
+{
+ return {
+ std::make_shared(ctx), // generated by codegen v1
+ std::make_shared(ctx),
+ };
+}
\ No newline at end of file
diff --git a/example/harmony/entry/src/main/ets/RNPackagesFactory.ets b/example/harmony/entry/src/main/ets/RNPackagesFactory.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8c3f5e2a00f68eaa296b286eadfbdb3667b1fb06
--- /dev/null
+++ b/example/harmony/entry/src/main/ets/RNPackagesFactory.ets
@@ -0,0 +1,15 @@
+/*
+*
+* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+* Use of this source code is governed by a MIT license that can be
+* found in the LICENSE file
+*
+*/
+
+import type {RNPackageContext, RNPackage} from '@rnoh/react-native-openharmony/ts';
+
+export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
+ return [
+
+ ];
+}
diff --git a/example/harmony/entry/src/main/ets/assets/fonts/Pacifico-Regular.ttf b/example/harmony/entry/src/main/ets/assets/fonts/Pacifico-Regular.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e7def95d3f44c82086f6e74d93fc0aadac7c454a
Binary files /dev/null and b/example/harmony/entry/src/main/ets/assets/fonts/Pacifico-Regular.ttf differ
diff --git a/example/harmony/entry/src/main/ets/assets/fonts/StintUltraCondensed-Regular.ttf b/example/harmony/entry/src/main/ets/assets/fonts/StintUltraCondensed-Regular.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..25c749e167bd5beef18360b13ae660f1c10ebc62
Binary files /dev/null and b/example/harmony/entry/src/main/ets/assets/fonts/StintUltraCondensed-Regular.ttf differ
diff --git a/example/harmony/entry/src/main/ets/entryability/EntryAbility.ets b/example/harmony/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..35746494ac1dda87b830c77681493aed4f389b61
--- /dev/null
+++ b/example/harmony/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+ * Use of this source code is governed by a MIT license that can be
+ * found in the LICENSE file.
+ */
+
+import {RNAbility} from '@rnoh/react-native-openharmony';
+import { AbilityConstant, Want } from '@kit.AbilityKit';
+
+export default class EntryAbility extends RNAbility {
+
+ onCreate(want: Want) {
+ super.onCreate(want)
+ }
+
+ getPagePath() {
+ return 'pages/Index';
+ }
+}
diff --git a/example/harmony/entry/src/main/ets/pages/Index.ets b/example/harmony/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..2649fbf883569a669489ac45eb4d0506a8ec28af
--- /dev/null
+++ b/example/harmony/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+ * Use of this source code is governed by a MIT license that can be
+ * found in the LICENSE file.
+ */
+
+import {
+ AnyJSBundleProvider,
+ ComponentBuilderContext,
+ FileJSBundleProvider,
+ MetroJSBundleProvider,
+ ResourceJSBundleProvider,
+ RNApp,
+ RNOHErrorDialog,
+ RNOHLogger,
+ TraceJSBundleProviderDecorator,
+ RNOHCoreContext
+} from '@rnoh/react-native-openharmony';
+import font from '@ohos.font';
+import { createRNPackages } from '../RNPackagesFactory';
+import { RNDateTimePicker, DATETIME_PICKER_VIEW_TYPE } from "@react-native-oh-tpl/datetimepicker"
+
+const arkTsComponentNames: Array = [
+ DATETIME_PICKER_VIEW_TYPE
+];
+
+@Builder
+export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
+ // There seems to be a problem with the placement of ArkTS components in mixed mode. Nested Stack temporarily avoided.
+ Stack() {
+ if (ctx.componentName === DATETIME_PICKER_VIEW_TYPE) {
+ RNDateTimePicker({
+ ctx: ctx.rnComponentContext,
+ tag: ctx.tag,
+ })
+ }
+ }
+ .position({ x: 0, y: 0 })
+
+}
+
+const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)
+
+/**
+ * If you want to use custom fonts, you need to register them here.
+ * We should support react-native-asset to handle registering fonts automatically.
+ */
+const fonts: font.FontOptions[] = [
+ {
+ familyName: 'Pacifico-Regular',
+ familySrc: '/assets/fonts/Pacifico-Regular.ttf'
+ },
+ {
+ familyName: 'StintUltraCondensed-Regular',
+ familySrc: '/assets/fonts/StintUltraCondensed-Regular.ttf'
+ }
+]
+
+@Entry
+@Component
+struct Index {
+ @StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined
+ @State shouldShow: boolean = false
+ private logger!: RNOHLogger
+ bundlePath: string = 'bunlde.harmony.js'
+ @State hasBundle: boolean = false
+
+ aboutToAppear() {
+ this.logger = this.rnohCoreContext!.logger.clone("Index")
+ const stopTracing = this.logger.clone("aboutToAppear").startTracing()
+ for (const customFont of fonts) {
+ font.registerFont(customFont)
+ }
+
+ this.shouldShow = true
+ stopTracing()
+ }
+
+ onBackPress(): boolean | undefined {
+ // NOTE: this is required since `Ability`'s `onBackPressed` function always
+ // terminates or puts the app in the background, but we want Ark to ignore it completely
+ // when handled by RN
+ this.rnohCoreContext!.dispatchBackPress()
+ return true
+ }
+
+ build() {
+ Column() {
+ if (this.rnohCoreContext && this.shouldShow) {
+ if (this.rnohCoreContext?.isDebugModeEnabled) {
+ RNOHErrorDialog({ ctx: this.rnohCoreContext })
+ }
+ RNApp({
+ rnInstanceConfig: {
+ createRNPackages,
+ enableNDKTextMeasuring: true,
+ enableBackgroundExecutor: false,
+ enableCAPIArchitecture: true,
+ arkTsComponentNames: arkTsComponentNames,
+ },
+ initialProps: { "foo": "bar" } as Record,
+ appKey: "app_name",
+ wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
+ onSetUp: (rnInstance) => {
+ rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
+ },
+ jsBundleProvider: new TraceJSBundleProviderDecorator(
+ new AnyJSBundleProvider([
+ new MetroJSBundleProvider(),
+ // NOTE: to load the bundle from file, place it in
+ // `/data/app/el2/100/base/com.rnoh.tester/files/bundle.harmony.js`
+ // on your device. The path mismatch is due to app sandboxing on HarmonyOS
+ new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
+ // new FileJSBundleProvider(context.filesDir + '/' + this.bundlePath),
+ new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),
+ new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
+ ]),
+ this.rnohCoreContext.logger),
+ })
+ }
+ Text("1233333333122 1212323")
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
diff --git a/example/harmony/entry/src/main/ets/pages/SurfaceDeadlockTest.ets b/example/harmony/entry/src/main/ets/pages/SurfaceDeadlockTest.ets
new file mode 100644
index 0000000000000000000000000000000000000000..88e4439681c4981d7ab7e1b87a46653a9e5a9c35
--- /dev/null
+++ b/example/harmony/entry/src/main/ets/pages/SurfaceDeadlockTest.ets
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+ * Use of this source code is governed by a MIT license that can be
+ * found in the LICENSE file.
+ */
+import { RNInstance, JSBundleProvider, RNAbility, RNSurface } from '@rnoh/react-native-openharmony'
+import { CustomComponentBuilder } from "@rnoh/react-native-openharmony/src/main/ets/RNOHCorePackage"
+import { SurfaceConfig2 } from '@rnoh/react-native-openharmony/src/main/ets/RNSurface'
+
+
+@Component
+export struct SurfaceDeadlockTest {
+ public jsBundleProvider: JSBundleProvider | undefined = undefined
+ public appKeys: string[] = []
+ public numberOfIterations: number = 1
+ @BuilderParam public buildCustomComponent!: CustomComponentBuilder
+ // -------------------------------------------------------------------------------------------------------------------
+ @StorageLink('RNAbility') private rnAbility: RNAbility = {} as RNAbility
+ private rnInstance!: RNInstance
+ @State private shouldShow: boolean = false
+ private shouldDestroyRNInstance: boolean = false
+ private cleanUpCallbacks: (() => void)[] = []
+
+ aboutToAppear() {
+ this.getOrCreateRNInstance().then(rnInstance => {
+ this.rnInstance = rnInstance
+ const jsBundleExecutionStatus = this.rnInstance.getBundleExecutionStatus(this.jsBundleProvider?.getURL())
+ if (this.jsBundleProvider && jsBundleExecutionStatus === undefined) {
+ this.rnInstance.runJSBundle(this.jsBundleProvider).then(() => {
+ this.shouldShow = true
+ })
+ return;
+ }
+ }).catch((reason: string | Error) => {
+ if (typeof reason === "string")
+ this.rnAbility.getLogger().error(reason)
+ else if (reason instanceof Error) {
+ this.rnAbility.getLogger().error(reason.message)
+ } else {
+ this.rnAbility.getLogger().error("Fatal exception")
+ }
+ })
+ }
+
+ aboutToDisappear() {
+ if (this.shouldDestroyRNInstance)
+ this.rnAbility.destroyAndUnregisterRNInstance(this.rnInstance)
+ this.cleanUpCallbacks.forEach(cleanUp => cleanUp())
+ }
+
+ private getOrCreateRNInstance(): Promise {
+ return this.rnAbility.createAndRegisterRNInstance({ createRNPackages: () => [] })
+ }
+
+ build() {
+ Stack() {
+ if (this.shouldShow) {
+ ForEach(this.appKeys, (appKey: string, idx) => {
+ Stack() {
+ Blinker({
+ minDelayInMs: 1000,
+ maxDelayInMs: 2000,
+ blinksCount: this.numberOfIterations,
+ randomnessPrecisionInMs: 500
+ }) {
+ RNSurface({
+ ctx: this.rnAbility.createRNOHContext({ rnInstance: this.rnInstance }),
+ surfaceConfig: {
+ initialProps: {},
+ appKey: appKey,
+ } as SurfaceConfig2,
+ buildCustomComponent: this.buildCustomComponent,
+ })
+ }
+ }.height(`${100 / this.appKeys.length}%`)
+ .position({ x: 0, y: `${(idx / this.appKeys.length) * 100}%` })
+ })
+ }
+ }.width("100%")
+ .height("100%")
+ }
+}
+
+
+@Component
+struct Blinker {
+ public minDelayInMs: number = 0
+ public maxDelayInMs: number = 1000
+ public blinksCount: number = 0
+ public randomnessPrecisionInMs: number = 250
+ @BuilderParam public renderChildren: () => void
+ private currentBlinksCount = 0
+ @State private isVisible: boolean = false
+ private timeout: number = 0
+
+ aboutToAppear() {
+ this.blink(this.minDelayInMs)
+ }
+
+ aboutToDisappear() {
+ clearTimeout(this.timeout)
+ }
+
+ private blink(ms: number) {
+ this.isVisible = !this.isVisible
+ this.currentBlinksCount += 1
+ if (this.currentBlinksCount >= this.blinksCount) {
+ if (this.timeout) {
+ clearTimeout(this.timeout)
+ }
+ this.isVisible = true
+ return;
+ }
+ this.timeout = setTimeout(() => {
+ this.blink(this.getNextDelay())
+ }, ms)
+ }
+
+ private getNextDelay(): number {
+ return ((Math.floor(Math.random() * (Number.MAX_VALUE / this.randomnessPrecisionInMs)) * this.randomnessPrecisionInMs) % this.maxDelayInMs) + this.minDelayInMs
+ }
+
+ build() {
+ Stack() {
+ if (this.isVisible) {
+ this.renderChildren()
+ }
+ }
+ }
+}
+
+
+
+
+
diff --git a/example/harmony/entry/src/main/ets/pages/TouchDisplayer.ets b/example/harmony/entry/src/main/ets/pages/TouchDisplayer.ets
new file mode 100644
index 0000000000000000000000000000000000000000..2c62df2983416a0fd5eca7e2e730283d139e0671
--- /dev/null
+++ b/example/harmony/entry/src/main/ets/pages/TouchDisplayer.ets
@@ -0,0 +1,37 @@
+@Component
+export struct TouchDisplayer {
+ @State currentTouches: TouchObject[] = []
+ @State touchIndicatorOpacity: number = 0
+ @BuilderParam buildChildren: () => void
+ build() {
+ Stack() {
+ this.buildChildren()
+ ForEach(this.currentTouches, (activeTouch: TouchObject) => {
+ Stack() {
+ }
+ .width(64)
+ .height(64)
+ .backgroundColor("blue")
+ .borderWidth(2)
+ .borderColor("white")
+ .opacity(this.touchIndicatorOpacity)
+ .position({ x: activeTouch.x - 32, y: activeTouch.y - 32 })
+ .borderRadius(1000)
+ .hitTestBehavior(HitTestMode.Transparent)
+ })
+ }
+ .width("100%")
+ .height("100%")
+ .hitTestBehavior(HitTestMode.Transparent)
+ .onTouch(e => {
+ this.currentTouches = e.touches
+ this.touchIndicatorOpacity = 0.5
+ animateTo({
+ duration: 500,
+ curve: Curve.Linear,
+ }, () => {
+ this.touchIndicatorOpacity = 0
+ })
+ })
+ }
+}
\ No newline at end of file
diff --git a/example/harmony/entry/src/main/module.json5 b/example/harmony/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..9f784b3416d687c39a4abd8e719c83e26b3707cd
--- /dev/null
+++ b/example/harmony/entry/src/main/module.json5
@@ -0,0 +1,49 @@
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "default"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ // below property is supported from 5.0.0 - it is needed by bundleManager.canOpenLink to check if the app can open some url
+ // "querySchemes": ["maps", "http", "https", "customDomain"],
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.INTERNET"
+ },
+ ],
+ "metadata": [
+ {
+ "name": "OPTLazyForEach",
+ "value": "true",
+ }
+ ],
+ "abilities": [
+ {
+ "name": "EntryAbility",
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:icon",
+ "startWindowBackground": "$color:start_window_background",
+ "visible": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/example/harmony/entry/src/main/resources/.gitignore b/example/harmony/entry/src/main/resources/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..037cea9e70bef8c906560a871a394f748ec2325d
--- /dev/null
+++ b/example/harmony/entry/src/main/resources/.gitignore
@@ -0,0 +1 @@
+rawfile/assets
diff --git a/example/harmony/entry/src/main/resources/base/element/color.json b/example/harmony/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/example/harmony/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/harmony/entry/src/main/resources/base/element/string.json b/example/harmony/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..074b2173f51352f71629252715526554911d44bb
--- /dev/null
+++ b/example/harmony/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "RN Tester"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/harmony/entry/src/main/resources/base/media/icon.png b/example/harmony/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..c0f05abe7eb110a3c4958a48f71ea15b28bae5d3
Binary files /dev/null and b/example/harmony/entry/src/main/resources/base/media/icon.png differ
diff --git a/example/harmony/entry/src/main/resources/base/profile/main_pages.json b/example/harmony/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/example/harmony/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/example/harmony/entry/src/main/resources/rawfile/1.txt b/example/harmony/entry/src/main/resources/rawfile/1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..71f6ee3dfcd13fad21fc73e697c7c5a3c31ec039
--- /dev/null
+++ b/example/harmony/entry/src/main/resources/rawfile/1.txt
@@ -0,0 +1 @@
+text test
\ No newline at end of file
diff --git a/example/harmony/format.ps1 b/example/harmony/format.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..7735881fded75cc61ee05ec623e0848b85f6d639
--- /dev/null
+++ b/example/harmony/format.ps1
@@ -0,0 +1,12 @@
+$directoryPath = Split-Path -Parent $MyInvocation.MyCommand.Path
+$filePaths = Get-ChildItem $directoryPath -Recurse -Include *.h, *.cpp |
+Where-Object {
+ $_.DirectoryName -notmatch 'third-party' -and
+ $_.DirectoryName -notmatch 'patches' -and
+ $_.DirectoryName -notmatch 'node_modules' -and
+ $_.DirectoryName -notmatch '.cxx' -and
+ $_.DirectoryName -notmatch 'build'
+}
+foreach ($filePath in $filePaths) {
+ & "clang-format.exe" -style=file -i $filePath.FullName
+}
\ No newline at end of file
diff --git a/example/harmony/hvigor/.gitignore b/example/harmony/hvigor/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..aa1ec1ea0618124672d14a63d00d943240f2db2a
--- /dev/null
+++ b/example/harmony/hvigor/.gitignore
@@ -0,0 +1 @@
+*.tgz
diff --git a/example/harmony/hvigor/hvigor-config.json5 b/example/harmony/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c8ba182673e80fbc3da9e614580e9453b718cd3b
--- /dev/null
+++ b/example/harmony/hvigor/hvigor-config.json5
@@ -0,0 +1,21 @@
+{
+ "modelVersion": "5.0.0",
+ "dependencies": {
+ },
+ "execution": {
+ // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
+ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
+ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
+ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
+ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
+ },
+ "logging": {
+ // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
+ },
+ "debugging": {
+ "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
+ },
+ "nodeOptions": {
+ // "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */
+ }
+}
\ No newline at end of file
diff --git a/example/harmony/hvigorfile.ts b/example/harmony/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6478186902c0c1ad7c966a929c7d6b7d8ae7a9f3
--- /dev/null
+++ b/example/harmony/hvigorfile.ts
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { appTasks } from '@ohos/hvigor-ohos-plugin';
\ No newline at end of file
diff --git a/example/harmony/oh-package.json5 b/example/harmony/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..6650947b07a5c5ef945fac1bce2e68ef4280c305
--- /dev/null
+++ b/example/harmony/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "modelVersion": "5.0.0",
+ "license": "ISC",
+ "name": "rnoh",
+ "description": "example description",
+ "repository": {},
+ "version": "1.0.0",
+ "overrides": {
+ "@rnoh/react-native-openharmony": "^0.72.38"
+ },
+ "dynamicDependencies": {}
+}
\ No newline at end of file
diff --git a/example/harmony/react-native-openharmony-0.72.38.har b/example/harmony/react-native-openharmony-0.72.38.har
new file mode 100644
index 0000000000000000000000000000000000000000..4b633ae458c0b485288a01ac93df131ea85413ae
Binary files /dev/null and b/example/harmony/react-native-openharmony-0.72.38.har differ
diff --git a/example/index.js b/example/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..3910bba3658625ea2f806748c5ef16b6293ac34f
--- /dev/null
+++ b/example/index.js
@@ -0,0 +1,5 @@
+import {AppRegistry, View, Text} from 'react-native';
+import {name as appName} from './app.json';
+import DateTimePickerTestDemo from './src/DateTimePickerTestDemo';
+
+AppRegistry.registerComponent(appName, () => DateTimePickerTestDemo);
\ No newline at end of file
diff --git a/example/jest.config.js b/example/jest.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..3745fc223702d5de74319e30d185b1dd5960d87b
--- /dev/null
+++ b/example/jest.config.js
@@ -0,0 +1,5 @@
+/** @type {import('ts-jest').JestConfigWithTsJest} */
+module.exports = {
+ preset: 'ts-jest',
+ testEnvironment: 'node',
+};
diff --git a/example/metro.config.js b/example/metro.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..f33c325ac1fad6c7733a76bfe002d136fb442c8f
--- /dev/null
+++ b/example/metro.config.js
@@ -0,0 +1,24 @@
+const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config');
+const {createHarmonyMetroConfig} = require('react-native-harmony/metro.config');
+
+/**
+ * @type {import("metro-config").ConfigT}
+ */
+const config = {
+ transformer: {
+ getTransformOptions: async () => ({
+ transform: {
+ experimentalImportSupport: false,
+ inlineRequires: true,
+ },
+ }),
+ },
+};
+
+module.exports = mergeConfig(
+ getDefaultConfig(__dirname),
+ createHarmonyMetroConfig({
+ reactNativeHarmonyPackageName: 'react-native-harmony',
+ }),
+ config,
+);
diff --git a/example/package.json b/example/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..dbf7d3e05fc8a9b538b4f8a56b71e067a238d399
--- /dev/null
+++ b/example/package.json
@@ -0,0 +1,67 @@
+{
+ "name": "react-native-harmony-tester",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "fast-install-project": "cd ../ && npm i --legacy-peer-deps && npm run pack && cd ./example && npm i --legacy-peer-deps",
+ "fast:pkg": "npm run fast-install-project && npm run dev",
+ "reStart": "npm run install:pkg && npm run codegen && hdc rport tcp:8081 tcp:8081 && react-native start",
+ "start": "hdc rport tcp:8081 tcp:8081 && react-native start",
+ "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",
+ "pack:pkg": "cd ../ && npm run pack && cd ./example",
+ "install:pkg": "npm uninstall @react-native-ohos/datetimepicker && npm run pack:pkg && npm i @react-native-ohos/datetimepicker@file:../react-native-ohos-datetimepicker-7.6.2.tgz",
+ "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false",
+ "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true",
+ "postinstall": "node ./scripts/create-build-profile"
+ },
+ "dependencies": {
+ "@gorhom/portal": "^1.0.14",
+ "@react-native-ohos/datetimepicker": "file:../react-native-ohos-datetimepicker-7.6.2.tgz",
+ "@rnoh/testerino": "npm:@react-native-oh-tpl/testerino@0.0.9",
+ "react": "18.2.0",
+ "react-native": "0.72.5",
+ "react-native-harmony": "npm:@react-native-oh/react-native-harmony@^0.72.32"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.20.0",
+ "@babel/preset-env": "^7.20.0",
+ "@babel/runtime": "^7.20.0",
+ "@react-native-community/eslint-config": "^3.2.0",
+ "@react-native/eslint-config": "^0.74.0",
+ "@react-native/metro-config": "^0.72.6",
+ "@tsconfig/react-native": "^2.0.2",
+ "@types/chai": "^4.3.4",
+ "@types/d3-scale-chromatic": "^3.0.0",
+ "@types/fs-extra": "^11.0.1",
+ "@types/jest": "^29.5.5",
+ "@types/metro-config": "^0.76.2",
+ "@types/react": "17.0.14",
+ "@types/react-dom": "17.0.14",
+ "@types/react-test-renderer": "^18.0.0",
+ "babel-jest": "^29.2.1",
+ "csv-parser": "^3.0.0",
+ "eslint": "^8.19.0",
+ "eslint-plugin-prettier": "^5.0.1",
+ "fs-extra": "^11.1.1",
+ "husky": "^8.0.3",
+ "jest": "^29.7.0",
+ "json5": "^2.2.3",
+ "metro": "^0.76.3",
+ "metro-config": "^0.76.3",
+ "metro-react-native-babel-preset": "0.73.9",
+ "prettier": "3.2.4",
+ "react-test-renderer": "18.2.0",
+ "simple-statistics": "^7.8.3",
+ "ts-jest": "^29.1.1",
+ "typescript": "^5.3.2",
+ "yargs": "^17.7.2"
+ },
+ "overrides": {
+ "@rnoh/react-native-harmony-cli": "npm:@react-native-oh/react-native-harmony-cli@^0.0.27",
+ "@react-native-community/cli": "11.4.1",
+ "@react-native/codegen": "0.74.0"
+ },
+ "resolutions": {
+ "@react-native-community/cli": "11.4.1"
+ }
+}
diff --git a/example/react-native.config.js b/example/react-native.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..4a038ab52d08072540e95ca80d06f5e6afe7e867
--- /dev/null
+++ b/example/react-native.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ project: {
+ },
+ assets: ['./assets/fonts/'],
+};
diff --git a/example/scripts/create-build-profile.js b/example/scripts/create-build-profile.js
new file mode 100644
index 0000000000000000000000000000000000000000..a7841d078f1258af521d389da9dc43c718903c6e
--- /dev/null
+++ b/example/scripts/create-build-profile.js
@@ -0,0 +1,39 @@
+const fs = require('fs');
+const JSON5 = require('json5');
+const path = require('path');
+
+const templatePath = path.join(
+ __dirname,
+ '..',
+ 'harmony',
+ 'build-profile.template.json5',
+);
+const existingProfilePath = path.join(
+ __dirname,
+ '..',
+ 'harmony',
+ 'build-profile.json5',
+);
+
+if (fs.existsSync(existingProfilePath)) {
+ let existingProfile = JSON5.parse(
+ fs.readFileSync(existingProfilePath, 'utf-8'),
+ );
+ let template = JSON5.parse(fs.readFileSync(templatePath, 'utf-8'));
+ let signingConfigs =
+ existingProfile.app && existingProfile.app.signingConfigs;
+
+ existingProfile = {...template};
+
+ if (signingConfigs) {
+ existingProfile.app.signingConfigs = signingConfigs;
+ }
+
+ fs.writeFileSync(
+ existingProfilePath,
+ JSON5.stringify(existingProfile, null, 2),
+ );
+} else {
+ // File doesn't exist, create a copy from the template
+ fs.copyFileSync(templatePath, existingProfilePath);
+}
\ No newline at end of file
diff --git a/example/src/DateTimePickerTestDemo.tsx b/example/src/DateTimePickerTestDemo.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..66734a47708330c9a2e7f355b6ee19f0e0fb0449
--- /dev/null
+++ b/example/src/DateTimePickerTestDemo.tsx
@@ -0,0 +1,339 @@
+import React, { Component } from 'react';
+import { StyleSheet, View, ScrollView, Text, Button } from 'react-native';
+import { Tester, TestSuite, TestCase } from '@rnoh/testerino';
+import DateTimePicker from '@react-native-community/datetimepicker';
+
+const STYLES = StyleSheet.create({
+ defaultPickerStyle: {
+ width: 150,
+ height: 50,
+ backgroundColor: '#ffffff'
+ },
+ MDDSStyle: {
+ width: 180,
+ height: 60,
+ backgroundColor: '#ff0000'
+ },
+ MDDCStyle: {
+ width: 210,
+ height: 70,
+ backgroundColor: '#00ff00'
+ },
+ MTStyle: {
+ width: 240,
+ height: 80,
+ backgroundColor: '#0000ff'
+ }
+});
+
+interface ComponentStyle {
+ width: number,
+ height: number,
+ backgroundColor: string
+}
+
+interface State {
+ mode: number,
+ MDDSValue: Date,
+ MDDCValue: Date,
+ MTValue: Date,
+ display: number,
+ MDDSStyle: ComponentStyle,
+ MDDCStyle: ComponentStyle,
+ MTStyle: ComponentStyle,
+
+ is24Hour: boolean,
+ maximumDate: Date,
+ minimumDate: Date,
+ MDDSDisabled: boolean,
+ MDDCDisabled: boolean,
+ MTDisabled: boolean,
+ textColor: string,
+}
+
+const modeList = ['date', 'time']
+const displayList = ['spinner', 'compact', 'inline']
+
+export class DateTimePickerTestDemo extends Component {
+
+ state: State = {
+ mode: 0,
+ MDDSValue: new Date('2024-07-24'),
+ MDDCValue: new Date('2024-07-24'),
+ MTValue: new Date('2024-07-24'),
+ display: 0,
+ MDDSStyle: {
+ width: 150,
+ height: 50,
+ backgroundColor: '#ffffff'
+ },
+ MDDCStyle: {
+ width: 150,
+ height: 50,
+ backgroundColor: '#ffffff'
+ },
+ MTStyle: {
+ width: 150,
+ height: 50,
+ backgroundColor: '#ffffff'
+ },
+ is24Hour: true,
+ maximumDate: new Date('2030-01-01'),
+ minimumDate: new Date('2008-10-01'),
+ MDDSDisabled: false,
+ MDDCDisabled: false,
+ MTDisabled: false,
+ textColor: '#000000'
+ }
+
+ render(): React.ReactNode {
+ const { mode, MDDSValue, MDDCValue, MTValue, display, MDDSStyle, MDDCStyle, MTStyle, is24Hour, maximumDate,
+ minimumDate, MDDSDisabled, MDDCDisabled, MTDisabled, textColor } = this.state;
+ return
+
+
+ {
+ return
+ 当前mode是:{modeList[mode]}
+
+ ;
+ }}
+ assert={async ({ expect, state }) => { expect(state).to.be.true; }}
+ />
+ {
+ return
+ 当前display是:{displayList[display]}
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+ 当前日期是:{MDDSValue.toDateString()}
+ { this.setState({ MDDSValue: date }); setState(true) }} />
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+ 当前日期是:{MDDCValue.toDateString()}
+ { this.setState({ MDDCValue: date }); setState(true) }} />
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+ 当前时间是:{MTValue.toTimeString()}
+ { this.setState({ MTValue: new Date(e.nativeEvent.timestamp) }); setState(true) }} />
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+ {
+ return
+
+ ;
+ }}
+ assert={async ({ expect, state }) => {
+ expect(state).to.be.true;
+ }}
+ />
+
+
+
+ }
+}
+export default DateTimePickerTestDemo
\ No newline at end of file
diff --git a/example/tsconfig.json b/example/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..9a2c8c222cb885dde1a7a015f7dfe57de4828c85
--- /dev/null
+++ b/example/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@tsconfig/react-native/tsconfig.json",
+ "compilerOptions": {
+ "jsx": "react-native",
+ "paths": {
+ "react-native": [
+ "./node_modules/react-native-harmony"
+ ],
+ },
+ },
+ "exclude": [
+ "harmony"
+ ]
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker.har b/harmony/datetimepicker.har
new file mode 100644
index 0000000000000000000000000000000000000000..8b87ac6a5151238ee91ba169ffa930397b7c6158
Binary files /dev/null and b/harmony/datetimepicker.har differ
diff --git a/harmony/datetimepicker/.gitignore b/harmony/datetimepicker/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..a751d23f51a2d727dcb269d9664025f96f21c5ea
--- /dev/null
+++ b/harmony/datetimepicker/.gitignore
@@ -0,0 +1,7 @@
+/node_modules
+/oh_modules
+/oh-package-lock.json5
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/harmony/datetimepicker/BuildProfile.ets b/harmony/datetimepicker/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a6676baef507048138478d15d4e30d4754be393d
--- /dev/null
+++ b/harmony/datetimepicker/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '7.6.2';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/LICENSE b/harmony/datetimepicker/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..c5c85db4f4c15e42b3089f323848965c19e33cae
--- /dev/null
+++ b/harmony/datetimepicker/LICENSE
@@ -0,0 +1,21 @@
+ MIT License
+
+ Copyright (C) 2023 Huawei Device Co., Ltd.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
diff --git a/harmony/datetimepicker/OAT.xml b/harmony/datetimepicker/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bf636592789e096e2b405ed0b4dfc7e1b018911d
--- /dev/null
+++ b/harmony/datetimepicker/OAT.xml
@@ -0,0 +1,38 @@
+
+
+
+ LICENSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/harmony/datetimepicker/README.OpenSource b/harmony/datetimepicker/README.OpenSource
new file mode 100644
index 0000000000000000000000000000000000000000..6a6dfa0b4afa0dcac5a42e24ade80e2f787dc7b1
--- /dev/null
+++ b/harmony/datetimepicker/README.OpenSource
@@ -0,0 +1,11 @@
+[
+ {
+ "Name": "datetimepicker",
+ "License": "MIT License",
+ "License File": "https://github.com/react-native-datetimepicker/datetimepicker/blob/master/LICENSE.md",
+ "Version Number": "7.6.2",
+ "Owner" : "Martijn Swaagman "
+ "Upstream URL": "https://github.com/react-native-datetimepicker/datetimepicker",
+ "Description": "datetimepicker, React Native date & time picker component."
+ }
+]
\ No newline at end of file
diff --git a/harmony/datetimepicker/README.md b/harmony/datetimepicker/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a7db105d35f717a7aff9df2f26ba8518b07318c6
--- /dev/null
+++ b/harmony/datetimepicker/README.md
@@ -0,0 +1,262 @@
+> 模板版本:v0.0.1
+
+
+
@react-native-community/datetimepicker
+
+
+
+
+
+
+
+
+
+
+## 安装与使用
+
+进入到工程目录并输入以下命令:
+
+
+
+**正在 npm 发布中,当前请先从仓库[Release](https://github.com/react-native-oh-library/datetimepicker/releases)中获取库 tgz,通过使用本地依赖来安装本库。**
+
+#### **yarn**
+
+```bash
+yarn add xxx
+```
+
+#### **npm**
+
+```bash
+npm install xxx
+```
+
+
+
+下面的代码展示了这个库的基本使用场景:
+
+```js
+import DateTimePicker from '@react-native-community/datetimepicker';
+
+export const App = () => {
+ const [date, setDate] = useState(new Date(1598051730000));
+ const [mode, setMode] = useState('date');
+ const [show, setShow] = useState(false);
+
+ const onChange = (event, selectedDate) => {
+ const currentDate = selectedDate;
+ setShow(false);
+ setDate(currentDate);
+ };
+
+ const showMode = (currentMode) => {
+ setShow(true);
+ setMode(currentMode);
+ };
+
+ const showDatepicker = () => {
+ showMode('date');
+ };
+
+ const showTimepicker = () => {
+ showMode('time');
+ };
+
+ return (
+
+
+
+ selected: {date.toLocaleString()}
+ {show && (
+
+ )}
+
+ );
+};
+```
+
+## Link
+
+目前鸿蒙暂不支持 AutoLink,所以 Link 步骤需要手动配置。
+
+首先需要使用 DevEco Studio 打开项目里的鸿蒙工程 `harmony`
+
+### 引入原生端代码
+
+目前有两种方法:
+
+1. 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
+2. 直接链接源码。
+
+方法一:通过 har 包引入
+打开 `entry/oh-package.json5`,添加以下依赖
+
+```json
+"dependencies": {
+ "rnoh": "file:../rnoh",
+ "rnoh-datetimepicker": "file:../../node_modules/@react-native-community/datetimepicker/harmony/datetimepicker.har"
+ }
+```
+
+点击右上角的 `sync` 按钮
+
+或者在终端执行:
+
+```bash
+cd entry
+ohpm install
+```
+
+方法二:直接链接源码
+打开 `entry/oh-package.json5`,添加以下依赖
+
+```json
+"dependencies": {
+ "rnoh": "file:../rnoh",
+ "rnoh-datetimepicker": "file:../../node_modules/@react-native-community/datetimepicker/harmony/datetimepicker"
+ }
+```
+
+打开终端,执行:
+
+```bash
+cd entry
+ohpm install --no-link
+```
+
+### 配置 CMakeLists 和引入 datetimepicker
+
+打开 `entry/src/main/cpp/CMakeLists.txt`,添加:
+
+```diff
+project(rnapp)
+cmake_minimum_required(VERSION 3.4.1)
+set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
+
+add_subdirectory("${RNOH_CPP_DIR}" ./rn)
+
+# RNOH_BEGIN: add_package_subdirectories
+add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
++ add_subdirectory("${OH_MODULE_DIR}/rnoh-datetimepicker/src/main/cpp" ./datetimepicker)
+# RNOH_END: add_package_subdirectories
+
+add_library(rnoh_app SHARED
+ "./PackageProvider.cpp"
+ "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
+)
+
+target_link_libraries(rnoh_app PUBLIC rnoh)
+
+# RNOH_BEGIN: link_packages
+target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
++ target_link_libraries(rnoh_app PUBLIC rnoh_datetime_picker)
+# RNOH_END: link_packages
+```
+
+打开 `entry/src/main/cpp/PackageProvider.cpp`,添加:
+
+```diff
+#include "RNOH/PackageProvider.h"
+#include "SamplePackage.h"
++ #include "DateTimePickerPackage.h"
+
+using namespace rnoh;
+
+std::vector> PackageProvider::getPackages(Package::Context ctx) {
+ return {
+ std::make_shared(ctx),
++ std::make_shared(ctx)
+ };
+}
+```
+
+### 在 ArkTs 侧引入 DateTimePicker 组件
+
+打开 `entry/src/main/ets/pages/index.ets`,添加:
+
+```diff
+import {
+ RNApp,
+ ComponentBuilderContext,
+ RNAbility,
+ AnyJSBundleProvider,
+ MetroJSBundleProvider,
+ ResourceJSBundleProvider,
+} from 'rnoh'
+import { SampleView, SAMPLE_VIEW_TYPE, PropsDisplayer } from "rnoh-sample-package"
+import { createRNPackages } from '../RNPackagesFactory'
++ import { RNDateTimePicker, DATETIME_PICKER_VIEW_TYPE } from "rnoh-datetimepicker"
+
+@Builder
+function CustomComponentBuilder(ctx: ComponentBuilderContext) {
+ if (ctx.descriptor.type === SAMPLE_VIEW_TYPE) {
+ SampleView({
+ ctx: ctx.rnohContext,
+ tag: ctx.descriptor.tag,
+ buildCustomComponent: CustomComponentBuilder
+ })
+ }
++ else if (ctx.descriptor.type === DATETIME_PICKER_VIEW_TYPE) {
++ RNDateTimePicker({
++ ctx: ctx.rnohContext,
++ tag: ctx.descriptor.tag,
++ buildCustomComponent: CustomComponentBuilder
++ })
++ }
+ ...
+}
+...
+```
+
+### 运行
+
+点击右上角的 `sync` 按钮
+
+或者在终端执行:
+
+```bash
+cd entry
+ohpm install
+```
+
+然后编译、运行即可。
+
+## 兼容性
+
+要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。
+
+请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:[<@react-native-oh-library/datetimepicker> Releases](https://github.com/react-native-oh-library/datetimepicker/releases/tag/7.6.2-0.0.2)
+
+## 属性
+
+| 名称 | 说明 | 类型 | 是否必填 | 原库平台 | 鸿蒙支持 |
+| ----------- | ------------------------------------------------------------------------- | -------- | -------- | ------------------------ | ---------------------------------------------------------- |
+| mode | Defines the type of the picker | string | 否 | All | partially (仅支持 date/time 模式) |
+| style | Sets style directly on picker component. | object | 否 | IOS only | yes |
+| display | Defines the visual display of the picker. The default value is "default". | string | 否 | All | partially (支持"default","spinner","compact","inline") |
+| onChange | Date change handler. | function | 否 | All | partially (仅支持 type 为 set 类型) |
+| value | Defines the date or time value used in the component. | Date | 是 | All | partially (仅 mode=date 且 display=spinner 时支持动态设置) |
+| is24Hour | Allows changing of the time picker to a 24-hour format. | bool | 否 | Windows and Android only | yes |
+| maximumDate | Defines the maximum date that can be selected | Date | 否 | All | partially (仅支持在 mode=date 且 display=spinner 时设置) |
+| minimumDate | Defines the minimum date that can be selected. | Date | 否 | All | partially (仅支持在 mode=date 且 display=spinner 时设置) |
+| disabled | If true, the user won't be able to interact with the view. | bool | 否 | IOS only | yes |
+| textColor | Allows changing of the textColor of the date picker. | string | 否 | IOS only | partially (仅支持在 mode=date 且 display=compact 时设置) |
+
+## 遗留问题
+
+- [ ] 部分接口,未适配
+
+## 其他
+
+## 开源协议
+
+本项目基于 [The MIT License (MIT)](https://github.com/react-native-oh-library/datetimepicker/blob/harmony/LICENSE) ,请自由地享受和参与开源。
diff --git a/harmony/datetimepicker/build-profile.json5 b/harmony/datetimepicker/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..eae947d455f64cd651bcc4b28bf4d60c41758073
--- /dev/null
+++ b/harmony/datetimepicker/build-profile.json5
@@ -0,0 +1,10 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/hvigorfile.ts b/harmony/datetimepicker/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b4b93187c42a917f5a6ec6e6be6def50e3597f07
--- /dev/null
+++ b/harmony/datetimepicker/hvigorfile.ts
@@ -0,0 +1,25 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2023 Huawei Device Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANT KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { harTasks } from '@ohos/hvigor-ohos-plugin';
diff --git a/harmony/datetimepicker/index.ets b/harmony/datetimepicker/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..e8972514f3ec1aa22861304ea81347dfaf56d15e
--- /dev/null
+++ b/harmony/datetimepicker/index.ets
@@ -0,0 +1,24 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2023 Huawei Device Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+export * from './src/main/ets/RNDateTimePicker'
\ No newline at end of file
diff --git a/harmony/datetimepicker/oh-package.json5 b/harmony/datetimepicker/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..547a817916c555a0f2020df81b117083e150600c
--- /dev/null
+++ b/harmony/datetimepicker/oh-package.json5
@@ -0,0 +1,15 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {
+ },
+ "name": "@react-native-ohos/datetimepicker",
+ "description": "date-time-picker in harmony",
+ "main": "index.ets",
+ "version": "7.6.2",
+ "dependencies": {
+ "@rnoh/react-native-openharmony": "^0.72.38"
+ }
+}
+
+
diff --git a/harmony/datetimepicker/src/main/cpp/CMakeLists.txt b/harmony/datetimepicker/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3218284eabd1c8ca3b6c01d9fe332749e1ded2e3
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.13)
+set(CMAKE_VERBOSE_MAKEFILE on)
+
+set(rnoh_datetime_picker_generated_dir "${CMAKE_CURRENT_SOURCE_DIR}/generated")
+file(GLOB_RECURSE rnoh_datetime_picker_generated_SRC "${rnoh_datetime_picker_generated_dir}/**/*.cpp")
+file(GLOB rnoh_datetime_picker_SRC CONFIGURE_DEPENDS *.cpp)
+add_library(rnoh_datetime_picker SHARED ${rnoh_datetime_picker_SRC} ${rnoh_datetime_picker_generated_SRC})
+target_include_directories(rnoh_datetime_picker PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${rnoh_datetime_picker_generated_dir})
+target_link_libraries(rnoh_datetime_picker PUBLIC rnoh)
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/cpp/DateTimePickerPackage.h b/harmony/datetimepicker/src/main/cpp/DateTimePickerPackage.h
new file mode 100644
index 0000000000000000000000000000000000000000..01445a36c0114dcda9733c47e97d7f4f0060a06b
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/DateTimePickerPackage.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+ * Use of this source code is governed by a MIT license that can be
+ * found in the LICENSE file.
+ */
+
+#pragma once
+
+#include "generated/RNOH/generated/BaseDatetimepickerPackage.h"
+
+namespace rnoh {
+class DateTimePickerPackage : public BaseDatetimepickerPackage {
+ using Super = BaseDatetimepickerPackage;
+// using Super::Super;
+
+public:
+ DateTimePickerPackage(Package::Context ctx) : Super(ctx) {}
+};
+} // namespace rnoh
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/cpp/generated/RNOH/generated/BaseDatetimepickerPackage.h b/harmony/datetimepicker/src/main/cpp/generated/RNOH/generated/BaseDatetimepickerPackage.h
new file mode 100644
index 0000000000000000000000000000000000000000..96185c5a0cc7e85bdc4c489854498fd6fe82098d
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/RNOH/generated/BaseDatetimepickerPackage.h
@@ -0,0 +1,67 @@
+/**
+ * This code was generated by "react-native codegen-lib-harmony"
+ */
+
+#pragma once
+
+#include
+#include "RNOH/Package.h"
+#include "RNOH/ArkTSTurboModule.h"
+#include "RNOH/generated/components/RNDateTimePickerViewJSIBinder.h"
+
+namespace rnoh {
+
+class BaseDatetimepickerPackageTurboModuleFactoryDelegate : public TurboModuleFactoryDelegate {
+ public:
+ SharedTurboModule createTurboModule(Context ctx, const std::string &name) const override {
+ return nullptr;
+ };
+};
+
+class BaseDatetimepickerPackageEventEmitRequestHandler : public EventEmitRequestHandler {
+ public:
+ void handleEvent(Context const &ctx) override {
+ auto eventEmitter = ctx.shadowViewRegistry->getEventEmitter(ctx.tag);
+ if (eventEmitter == nullptr) {
+ return;
+ }
+
+ std::vector supportedEventNames = {
+ "change",
+ "pickerDismiss",
+ };
+ if (std::find(supportedEventNames.begin(), supportedEventNames.end(), ctx.eventName) != supportedEventNames.end()) {
+ eventEmitter->dispatchEvent(ctx.eventName, ArkJS(ctx.env).getDynamic(ctx.payload));
+ }
+ }
+};
+
+
+class BaseDatetimepickerPackage : public Package {
+ public:
+ BaseDatetimepickerPackage(Package::Context ctx) : Package(ctx){};
+
+ std::unique_ptr createTurboModuleFactoryDelegate() override {
+ return std::make_unique();
+ }
+
+ std::vector createComponentDescriptorProviders() override {
+ return {
+ facebook::react::concreteComponentDescriptorProvider(),
+ };
+ }
+
+ ComponentJSIBinderByString createComponentJSIBinderByName() override {
+ return {
+ {"RNDateTimePickerView", std::make_shared()},
+ };
+ };
+
+ EventEmitRequestHandlers createEventEmitRequestHandlers() override {
+ return {
+ std::make_shared(),
+ };
+ }
+};
+
+} // namespace rnoh
diff --git a/harmony/datetimepicker/src/main/cpp/generated/RNOH/generated/components/RNDateTimePickerViewJSIBinder.h b/harmony/datetimepicker/src/main/cpp/generated/RNOH/generated/components/RNDateTimePickerViewJSIBinder.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa2a6e5a029639d7362e1a7753a8f551419403f8
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/RNOH/generated/components/RNDateTimePickerViewJSIBinder.h
@@ -0,0 +1,42 @@
+/**
+ * This code was generated by "react-native codegen-lib-harmony"
+ */
+
+#pragma once
+#include "RNOHCorePackage/ComponentBinders/ViewComponentJSIBinder.h"
+
+namespace rnoh {
+class RNDateTimePickerViewJSIBinder : public ViewComponentJSIBinder {
+ protected:
+ facebook::jsi::Object createNativeProps(facebook::jsi::Runtime &rt) override {
+ auto object = ViewComponentJSIBinder::createNativeProps(rt);
+ object.setProperty(rt, "maximumDate", true);
+ object.setProperty(rt, "minimumDate", true);
+ object.setProperty(rt, "date", true);
+ object.setProperty(rt, "locale", true);
+ object.setProperty(rt, "minuteInterval", true);
+ object.setProperty(rt, "mode", true);
+ object.setProperty(rt, "timeZoneOffsetInMinutes", true);
+ object.setProperty(rt, "timeZoneName", true);
+ object.setProperty(rt, "textColor", true);
+ object.setProperty(rt, "accentColor", true);
+ object.setProperty(rt, "themeVariant", true);
+ object.setProperty(rt, "displayIOS", true);
+ object.setProperty(rt, "is24Hour", true);
+ object.setProperty(rt, "enabled", true);
+ return object;
+ }
+
+ facebook::jsi::Object createBubblingEventTypes(facebook::jsi::Runtime &rt) override {
+ facebook::jsi::Object events(rt);
+ events.setProperty(rt, "topChange", createBubblingCapturedEvent(rt, "onChange"));
+ events.setProperty(rt, "topPickerDismiss", createBubblingCapturedEvent(rt, "onPickerDismiss"));
+ return events;
+ }
+
+ facebook::jsi::Object createDirectEventTypes(facebook::jsi::Runtime &rt) override {
+ facebook::jsi::Object events(rt);
+ return events;
+ }
+};
+} // namespace rnoh
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ComponentDescriptors.h b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ComponentDescriptors.h
new file mode 100644
index 0000000000000000000000000000000000000000..8adb5b6a6be44c4a1c094ecd284a82c157782c3d
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ComponentDescriptors.h
@@ -0,0 +1,22 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateComponentDescriptorH.js
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+using RNDateTimePickerViewComponentDescriptor = ConcreteComponentDescriptor;
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/EventEmitters.cpp b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/EventEmitters.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ced2247e51fce45b0091fa03f7952aea13dd5329
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/EventEmitters.cpp
@@ -0,0 +1,36 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateEventEmitterCpp.js
+ */
+
+#include
+
+
+namespace facebook {
+namespace react {
+
+void RNDateTimePickerViewEventEmitter::onChange(OnChange $event) const {
+ dispatchEvent("change", [$event=std::move($event)](jsi::Runtime &runtime) {
+ auto $payload = jsi::Object(runtime);
+ $payload.setProperty(runtime, "timestamp", $event.timestamp);
+$payload.setProperty(runtime, "utcOffset", $event.utcOffset);
+ return $payload;
+ });
+}
+
+
+void RNDateTimePickerViewEventEmitter::onPickerDismiss(OnPickerDismiss $event) const {
+ dispatchEvent("pickerDismiss", [](jsi::Runtime &runtime) {
+ auto $payload = jsi::Object(runtime);
+
+ return $payload;
+ });
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/EventEmitters.h b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/EventEmitters.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c3b95dcddaac7cd9956eff0f057fd31da514447
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/EventEmitters.h
@@ -0,0 +1,34 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateEventEmitterH.js
+ */
+#pragma once
+
+#include
+
+
+namespace facebook {
+namespace react {
+class RNDateTimePickerViewEventEmitter : public ViewEventEmitter {
+ public:
+ using ViewEventEmitter::ViewEventEmitter;
+
+ struct OnChange {
+ double timestamp;
+ int utcOffset;
+ };
+
+ struct OnPickerDismiss {
+
+ };
+ void onChange(OnChange value) const;
+
+ void onPickerDismiss(OnPickerDismiss value) const;
+};
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/Props.cpp b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/Props.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d5d9d71196203e19a65f70c7248ef108049ffa42
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/Props.cpp
@@ -0,0 +1,40 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GeneratePropsCpp.js
+ */
+
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+RNDateTimePickerViewProps::RNDateTimePickerViewProps(
+ const PropsParserContext &context,
+ const RNDateTimePickerViewProps &sourceProps,
+ const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
+
+ maximumDate(convertRawProp(context, rawProps, "maximumDate", sourceProps.maximumDate, {0.0})),
+ minimumDate(convertRawProp(context, rawProps, "minimumDate", sourceProps.minimumDate, {0.0})),
+ date(convertRawProp(context, rawProps, "date", sourceProps.date, {0.0})),
+ locale(convertRawProp(context, rawProps, "locale", sourceProps.locale, {})),
+ minuteInterval(convertRawProp(context, rawProps, "minuteInterval", sourceProps.minuteInterval, {0})),
+ mode(convertRawProp(context, rawProps, "mode", sourceProps.mode, {RNDateTimePickerViewMode::Date})),
+ timeZoneOffsetInMinutes(convertRawProp(context, rawProps, "timeZoneOffsetInMinutes", sourceProps.timeZoneOffsetInMinutes, {0.0})),
+ timeZoneName(convertRawProp(context, rawProps, "timeZoneName", sourceProps.timeZoneName, {})),
+ textColor(convertRawProp(context, rawProps, "textColor", sourceProps.textColor, {})),
+ accentColor(convertRawProp(context, rawProps, "accentColor", sourceProps.accentColor, {})),
+ themeVariant(convertRawProp(context, rawProps, "themeVariant", sourceProps.themeVariant, {RNDateTimePickerViewThemeVariant::Unspecified})),
+ displayIOS(convertRawProp(context, rawProps, "displayIOS", sourceProps.displayIOS, {RNDateTimePickerViewDisplayIOS::Default})),
+ is24Hour(convertRawProp(context, rawProps, "is24Hour", sourceProps.is24Hour, {true})),
+ enabled(convertRawProp(context, rawProps, "enabled", sourceProps.enabled, {true}))
+ {}
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/Props.h b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/Props.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5e8c19c3d481abcada236d0b56db642ee1cc62c
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/Props.h
@@ -0,0 +1,99 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GeneratePropsH.js
+ */
+#pragma once
+
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+enum class RNDateTimePickerViewMode { Date, Time, Datetime, Countdown };
+
+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, RNDateTimePickerViewMode &result) {
+ auto string = (std::string)value;
+ if (string == "date") { result = RNDateTimePickerViewMode::Date; return; }
+ if (string == "time") { result = RNDateTimePickerViewMode::Time; return; }
+ if (string == "datetime") { result = RNDateTimePickerViewMode::Datetime; return; }
+ if (string == "countdown") { result = RNDateTimePickerViewMode::Countdown; return; }
+ abort();
+}
+
+static inline std::string toString(const RNDateTimePickerViewMode &value) {
+ switch (value) {
+ case RNDateTimePickerViewMode::Date: return "date";
+ case RNDateTimePickerViewMode::Time: return "time";
+ case RNDateTimePickerViewMode::Datetime: return "datetime";
+ case RNDateTimePickerViewMode::Countdown: return "countdown";
+ }
+}
+enum class RNDateTimePickerViewThemeVariant { Dark, Light, Unspecified };
+
+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, RNDateTimePickerViewThemeVariant &result) {
+ auto string = (std::string)value;
+ if (string == "dark") { result = RNDateTimePickerViewThemeVariant::Dark; return; }
+ if (string == "light") { result = RNDateTimePickerViewThemeVariant::Light; return; }
+ if (string == "unspecified") { result = RNDateTimePickerViewThemeVariant::Unspecified; return; }
+ abort();
+}
+
+static inline std::string toString(const RNDateTimePickerViewThemeVariant &value) {
+ switch (value) {
+ case RNDateTimePickerViewThemeVariant::Dark: return "dark";
+ case RNDateTimePickerViewThemeVariant::Light: return "light";
+ case RNDateTimePickerViewThemeVariant::Unspecified: return "unspecified";
+ }
+}
+enum class RNDateTimePickerViewDisplayIOS { Default, Spinner, Compact, Inline };
+
+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, RNDateTimePickerViewDisplayIOS &result) {
+ auto string = (std::string)value;
+ if (string == "default") { result = RNDateTimePickerViewDisplayIOS::Default; return; }
+ if (string == "spinner") { result = RNDateTimePickerViewDisplayIOS::Spinner; return; }
+ if (string == "compact") { result = RNDateTimePickerViewDisplayIOS::Compact; return; }
+ if (string == "inline") { result = RNDateTimePickerViewDisplayIOS::Inline; return; }
+ abort();
+}
+
+static inline std::string toString(const RNDateTimePickerViewDisplayIOS &value) {
+ switch (value) {
+ case RNDateTimePickerViewDisplayIOS::Default: return "default";
+ case RNDateTimePickerViewDisplayIOS::Spinner: return "spinner";
+ case RNDateTimePickerViewDisplayIOS::Compact: return "compact";
+ case RNDateTimePickerViewDisplayIOS::Inline: return "inline";
+ }
+}
+
+class RNDateTimePickerViewProps final : public ViewProps {
+ public:
+ RNDateTimePickerViewProps() = default;
+ RNDateTimePickerViewProps(const PropsParserContext& context, const RNDateTimePickerViewProps &sourceProps, const RawProps &rawProps);
+
+#pragma mark - Props
+
+ double maximumDate{0.0};
+ double minimumDate{0.0};
+ double date{0.0};
+ std::string locale{};
+ int minuteInterval{0};
+ RNDateTimePickerViewMode mode{RNDateTimePickerViewMode::Date};
+ double timeZoneOffsetInMinutes{0.0};
+ std::string timeZoneName{};
+ SharedColor textColor{};
+ SharedColor accentColor{};
+ RNDateTimePickerViewThemeVariant themeVariant{RNDateTimePickerViewThemeVariant::Unspecified};
+ RNDateTimePickerViewDisplayIOS displayIOS{RNDateTimePickerViewDisplayIOS::Default};
+ bool is24Hour{true};
+ bool enabled{true};
+};
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ShadowNodes.cpp b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ShadowNodes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d0f96719c89f5a44ea57f59504a6fba63887f7c
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ShadowNodes.cpp
@@ -0,0 +1,19 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateShadowNodeCpp.js
+ */
+
+#include
+
+namespace facebook {
+namespace react {
+
+extern const char RNDateTimePickerViewComponentName[] = "RNDateTimePickerView";
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ShadowNodes.h b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ShadowNodes.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e371f58b3ab024b32a5f9261eb0a62e24220f71
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/ShadowNodes.h
@@ -0,0 +1,34 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateShadowNodeH.js
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+JSI_EXPORT extern const char RNDateTimePickerViewComponentName[];
+
+/*
+ * `ShadowNode` for component.
+ */
+using RNDateTimePickerViewShadowNode = ConcreteViewShadowNode<
+ RNDateTimePickerViewComponentName,
+ RNDateTimePickerViewProps,
+ RNDateTimePickerViewEventEmitter,
+ RNDateTimePickerViewState>;
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/States.cpp b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/States.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b98f589ad13297b275a01651c585233f9b23ff11
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/States.cpp
@@ -0,0 +1,18 @@
+
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateStateCpp.js
+ */
+#include
+
+namespace facebook {
+namespace react {
+
+
+
+} // namespace react
+} // namespace facebook
diff --git a/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/States.h b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/States.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3d0c5a1a31aeeec460516648c1422000a1edcd2
--- /dev/null
+++ b/harmony/datetimepicker/src/main/cpp/generated/react/renderer/components/datetimepicker/States.h
@@ -0,0 +1,36 @@
+/**
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
+ *
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
+ * once the code is regenerated.
+ *
+ * @generated by codegen project: GenerateStateH.js
+ */
+#pragma once
+
+#ifdef ANDROID
+#include
+#include
+#include
+#endif
+
+namespace facebook {
+namespace react {
+
+class RNDateTimePickerViewState {
+public:
+ RNDateTimePickerViewState() = default;
+
+#ifdef ANDROID
+ RNDateTimePickerViewState(RNDateTimePickerViewState const &previousState, folly::dynamic data){};
+ folly::dynamic getDynamic() const {
+ return {};
+ };
+ MapBuffer getMapBuffer() const {
+ return MapBufferBuilder::EMPTY();
+ };
+#endif
+};
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/ets/RNDateTimePicker.ets b/harmony/datetimepicker/src/main/ets/RNDateTimePicker.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8d2c4d55f75bc628459eb8dc62dce4153caba66b
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/RNDateTimePicker.ets
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+ * Use of this source code is governed by a MIT license that can be
+ * found in the LICENSE file.
+ */
+
+import {
+ Descriptor,
+ RNOHContext,
+ RNComponentContext,
+ ViewBaseProps,
+ RNViewBase,
+ RNOHLogger,
+ ComponentBuilderContext,
+ RNComponentFactory
+} from '@rnoh/react-native-openharmony'
+import { RNC } from "./generated/ts";
+import inputMethod from '@ohos.inputMethod';
+// import Logger from './Logger';
+
+// export const DATETIME_PICKER_VIEW_TYPE = "RNDateTimePicker"
+
+export interface ViewPagerProps extends ViewBaseProps {
+ maximumDate: string
+ minimumDate: string
+ date: string
+ locale: string
+ minuteInterval: number //
+ mode: string
+ timeZoneOffsetInMinutes: number //
+ timeZoneName: string //
+ textColor: string //
+ accentColor: string //
+ themeVariant: string //
+ displayIOS: string
+ enabled: boolean //
+ is24Hour: boolean //add 0926
+}
+
+export type PickerDescriptor = Descriptor<"RNDateTimePicker", ViewPagerProps>
+export const DATETIME_PICKER_VIEW_TYPE: string = RNC.RNDateTimePickerView.NAME
+// const TAG: string = "RNDateTimePicker"
+
+
+@Component
+export struct RNDateTimePicker {
+ // ctx!: RNOHContext
+ ctx!: RNComponentContext
+ tag: number = 0
+ @State private descriptor: RNC.RNDateTimePickerView.DescriptorWrapper = {} as RNC.RNDateTimePickerView.DescriptorWrapper
+ // private unregisterDescriptorChangesListener?: () => void = undefined
+ private logger: RNOHLogger | null = null;
+ // 存储需要在组件卸载时清理的回调函数
+ private cleanUpCallbacks: (() => void)[] = []
+ private eventEmitter: RNC.RNDateTimePickerView.EventEmitter | undefined = undefined
+ @State selectDate: Date = new Date()
+ @State isMilitaryTime: boolean = false //true=24h制
+ @State isLunar: boolean = false //true=显示农历
+
+ aboutToAppear() {
+
+ // this.descriptor = this.ctx.descriptorRegistry.getDescriptor(this.tag)
+ // 处理组件初始状态
+ this.onDescriptorWrapperChange(this.ctx.descriptorRegistry.findDescriptorWrapperByTag(this.tag)!)
+ // this.unregisterDescriptorChangesListener = this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag,
+ // (newDescriptor) => {
+ // this.descriptor = (newDescriptor as PickerDescriptor)
+ // 订阅组件状态的变化,然后放入cleanUpCallbacks等待清理
+ this.cleanUpCallbacks.push( this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag,
+ (_descriptor, newDescriptorWrapper) => {
+ // 更新组件状态
+ this.onDescriptorWrapperChange(newDescriptorWrapper! as RNC.RNDateTimePickerView.DescriptorWrapper)
+ }
+ ))
+ // Logger.debug(TAG,`[RNOH]: in RNDateTimePicker,descriptor change :${JSON.stringify(this.descriptor.props)}`)
+ this.logger = this.ctx?.logger.clone(RNC.RNDateTimePickerView.NAME);
+ this.isMilitaryTime = this.descriptor.props.is24Hour;
+ // this.selectDate = new Date(Number.parseInt(this.descriptor.props.date));
+ this.selectDate = new Date(this.descriptor.props.date);
+ // Logger.info(TAG,`[RNOH]: in RNDateTimePicker,propsout :${JSON.stringify(this.descriptor.props)}`)
+ // this.selectDate = new Date(Number.parseInt(this.descriptor.props.date));
+ // Logger.debug(TAG,`[RNOH]: RNDateTimePicker,out selectDate :${this.selectDate}`)
+ // this.isMilitaryTime = this.descriptor.props.is24Hour
+ }
+
+
+ onPageHide() {
+ // this.logger?.debug(TAG,`[RNOH]: in RNDateTimePicker,onPageHide`)
+ this.logger?.debug(`[RNOH]: in RNDateTimePicker,onPageHide`)
+
+ }
+
+ aboutToDisappear() {
+ // Logger.debug(TAG,`[RNOH]: in RNDateTimePicker,aboutToDisappear`)
+ // this.onPickerDismiss()
+ // this.unregisterDescriptorChangesListener?.()
+ // 执行所有清理回调
+ this.cleanUpCallbacks.forEach(cb => cb())
+ }
+ // 更新组件状态
+ private onDescriptorWrapperChange(descriptorWrapper: RNC.RNDateTimePickerView.DescriptorWrapper) {
+ this.logger?.info(`onDescriptorWrapperChange`)
+ this.descriptor = descriptorWrapper
+ }
+
+ onDateChange(dateIn: Date) {
+ this.logger?.debug(`RNOH in PickerView onChange,${JSON.stringify(dateIn)}`)
+ let unit = 1000 * 60
+ let time = dateIn.getTime()
+
+ //It is the offset in minutes between the selected date and UTC time.
+ let offset = time / unit;
+ // this.ctx.rnInstance.emitComponentEvent(
+ // this.descriptor.tag,
+ // DATETIME_PICKER_VIEW_TYPE,
+ // {
+ // type: "onChange",
+ // utcOffset: offset,
+ // timestamp: time
+ // }
+ // );
+ // 新版 codegen 的事件传递方式, 需调用eventEmitter中的emit方法
+ this.eventEmitter!.emit("change", { utcOffset: offset, timestamp: time });
+ }
+
+ onPickerDismiss() {
+ this.logger?.debug(`RNOH in PickerView onPickerDismiss`)
+ // this.ctx.rnInstance.emitComponentEvent(
+ // this.descriptor.tag,
+ // DATETIME_PICKER_VIEW_TYPE,
+ // {
+ // type: "onPickerDismiss"
+ // }
+ // );
+ this.eventEmitter!.emit("pickerDismiss", {});
+ }
+ //"default" - Automatically pick the best style available for the current platform & mode.
+ //"spinner" - the usual pre-iOS 14 appearance with a wheel from which you choose values
+ //"compact" - Affects only iOS 14 and later. Will fall back to "spinner" if not supported.
+ //"inline"
+ build() {
+ RNViewBase({ ctx: this.ctx, tag: this.tag }) {
+ // RNComponentFactory({ctx:this.ctx,tag:this.tag,buildCustomComponent:this.buildCustomComponent})
+ if (this.descriptor.props.mode === "date" || this.descriptor.props.mode === undefined) {
+ if (this.descriptor.props.displayIOS === "compact" || this.descriptor.props.displayIOS === "inline") {
+
+ CalendarPicker({ hintRadius: 17, selected: this.selectDate })
+
+ .edgeAlign(CalendarAlign.END)
+ // .textStyle({color:this.descriptor.props.textColor,font:{size:16,weight:FontWeight.Normal}})
+ .textStyle({ color: this.descriptor.props.textColor.toRGBAString() })
+ .enabled(this.descriptor.props.enabled)
+ .width("100%").height("100%")
+ .onChange((newDate:Date) => {
+ this.logger?.debug("CalendarPicker onChange:" + JSON.stringify(newDate))
+ //0927验证发现 没有执行回调
+ // this.selectDate.setFullYear(newDate.getFullYear(), newDate.getMonth(), newDate.getDay())
+ this.selectDate = newDate
+ this.onDateChange(this.selectDate)
+ })
+ } else if (this.descriptor.props.displayIOS === "spinner" || this.descriptor.props.displayIOS === "default") {
+ DatePicker({
+ start: this.descriptor.props.minimumDate != 0 ? new Date(this.descriptor.props.minimumDate) : new Date(1970, 0, 0),
+ end: this.descriptor.props.maximumDate != 0 ? new Date(this.descriptor.props.maximumDate) : new Date(2100, 0, 0),
+ selected: this.selectDate
+ })
+ // .disappearTextStyle({color:Color.Gray,font:{size:'16fp',weight:FontWeight.Bold}})
+ // .textStyle({color:'#ff182431',font:{size:'18fp',weight:FontWeight.Normal}})
+ // .selectedTextStyle({color:'#ff0000FF',font:{size:'26fp',weight:FontWeight.Regular}})
+ .lunar(this.isLunar)
+ .enabled(this.descriptor.props.enabled)
+ .width("100%").height("100%")
+ .onDateChange((value: Date) => {
+ // this.selectDate.setFullYear(value.year, value.month, value.day)
+ this.selectDate = value
+ this.logger?.debug("DatePicker,select current date is: "+ JSON.stringify(value))
+ this.onDateChange(this.selectDate)
+ })
+ }
+ } else if (this.descriptor.props.mode === "time") {
+ TimePicker({
+ selected: this.selectDate,
+ })
+ .useMilitaryTime(this.isMilitaryTime)
+ .enabled(this.descriptor.props.enabled)
+ .onChange((value: TimePickerResult) => {
+ this.selectDate.setHours(value.hour, value.minute)
+ this.logger?.debug('TimePicker,select current date is: ' + JSON.stringify(value))
+ this.onDateChange(this.selectDate)
+ })
+ // .disappearTextStyle({color:Color.Red,font:{size:15,weight:FontWeight.Lighter}})
+ // .textStyle({color:Color.Black,font: {size:20,weight:FontWeight.Normal}})
+ // .selectedTextStyle({color:Color.Blue,font:{size:30,weight:FontWeight.Bolder}})
+ .width("100%").height("100%")
+ }
+ // .position({y:this.descriptor.layoutMetrics.frame.origin.y, x:this.descriptor.layoutMetrics.frame.origin.x})
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/ets/RNDateTimePickerPackage.ts b/harmony/datetimepicker/src/main/ets/RNDateTimePickerPackage.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ffb92336ce218fe42b53b23429e8f3679939456a
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/RNDateTimePickerPackage.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
+ * Use of this source code is governed by a MIT license that can be
+ * found in the LICENSE file.
+ */
+
+import { RNPackage } from '@rnoh/react-native-openharmony/ts';
+import type {DescriptorWrapperFactoryByDescriptorTypeCtx, DescriptorWrapperFactoryByDescriptorType} from '@rnoh/react-native-openharmony/ts';
+import { RNC } from './generated/ts';
+
+export class RNDateTimePickerPackage extends RNPackage {
+ createDescriptorWrapperFactoryByDescriptorType(ctx:
+ DescriptorWrapperFactoryByDescriptorTypeCtx):
+ DescriptorWrapperFactoryByDescriptorType {
+ return {
+ [RNC.RNDateTimePickerView.NAME]: (ctx) =>
+ new RNC.RNDateTimePickerView.DescriptorWrapper(ctx.descriptor)
+ }
+ }
+}
diff --git a/harmony/datetimepicker/src/main/ets/generated/components/RNDateTimePickerView.ts b/harmony/datetimepicker/src/main/ets/generated/components/RNDateTimePickerView.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fd74400e12a0d4b3b80ef237cb93820166a7da4b
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/generated/components/RNDateTimePickerView.ts
@@ -0,0 +1,184 @@
+/**
+ * This code was generated by "react-native codegen-lib-harmony"
+ */
+
+import {
+ Descriptor as ComponentDescriptor,
+ ViewBaseProps,
+ ViewRawProps,
+ ViewDescriptorWrapperBase,
+ ColorValue,
+ Color,
+ RNInstance,
+ Tag,
+ RNComponentCommandReceiver,
+ ViewPropsSelector,
+} from '@rnoh/react-native-openharmony/ts';
+
+
+export namespace RNDateTimePickerView {
+ export const NAME = "RNDateTimePickerView" as const
+
+ export interface DirectRawProps {
+ maximumDate?: number;
+ minimumDate?: number;
+ date?: number;
+ locale?: string;
+ minuteInterval?: number;
+ mode?: 'date' | 'time' | 'datetime' | 'countdown';
+ timeZoneOffsetInMinutes?: number;
+ timeZoneName?: string;
+ textColor?: ColorValue;
+ accentColor?: ColorValue;
+ themeVariant?: 'dark' | 'light' | 'unspecified';
+ displayIOS?: 'default' | 'spinner' | 'compact' | 'inline';
+ is24Hour?: boolean;
+ enabled?: boolean;
+ }
+
+ export interface Props extends ViewBaseProps {}
+
+ export interface State {}
+
+ export interface RawProps extends ViewRawProps, DirectRawProps {}
+
+ export class PropsSelector extends ViewPropsSelector {
+ get maximumDate() {
+ return this.rawProps.maximumDate ?? 0;
+ }
+
+ get minimumDate() {
+ return this.rawProps.minimumDate ?? 0;
+ }
+
+ get date() {
+ return this.rawProps.date ?? 0;
+ }
+
+ get locale() {
+ return this.rawProps.locale;
+ }
+
+ get minuteInterval() {
+ return this.rawProps.minuteInterval ?? 0;
+ }
+
+ get mode() {
+ return this.rawProps.mode ?? 'date';
+ }
+
+ get timeZoneOffsetInMinutes() {
+ return this.rawProps.timeZoneOffsetInMinutes ?? 0;
+ }
+
+ get timeZoneName() {
+ return this.rawProps.timeZoneName;
+ }
+
+ get themeVariant() {
+ return this.rawProps.themeVariant ?? 'unspecified';
+ }
+
+ get displayIOS() {
+ return this.rawProps.displayIOS ?? 'default';
+ }
+
+ get is24Hour() {
+ return this.rawProps.is24Hour ?? true;
+ }
+
+ get enabled() {
+ return this.rawProps.enabled ?? true;
+ }
+
+
+ get textColor() {
+ if (this.rawProps.textColor) {
+ return Color.fromColorValue(this.rawProps.textColor)
+ } else {
+ return new Color({ r: 0, g: 0, b: 0, a: 255})
+ }
+ }
+
+ get accentColor() {
+ if (this.rawProps.accentColor) {
+ return Color.fromColorValue(this.rawProps.accentColor)
+ } else {
+ return new Color({ r: 0, g: 0, b: 0, a: 255})
+ }
+ }
+
+ }
+
+ export type Descriptor = ComponentDescriptor<
+ typeof NAME,
+ Props,
+ State,
+ RawProps
+ >;
+
+ export class DescriptorWrapper extends ViewDescriptorWrapperBase<
+ typeof NAME,
+ Props,
+ State,
+ RawProps,
+ PropsSelector
+ > {
+ protected createPropsSelector() {
+ return new PropsSelector(this.descriptor.props, this.descriptor.rawProps)
+ }
+ }
+
+ export interface EventPayloadByName {
+ "change": {timestamp: number, utcOffset: number}
+ "pickerDismiss": {}
+ }
+
+ export class EventEmitter {
+ constructor(private rnInstance: RNInstance, private tag: Tag) {}
+
+ emit(eventName: TEventName, payload: EventPayloadByName[TEventName]) {
+ this.rnInstance.emitComponentEvent(this.tag, eventName, payload)
+ }
+ }
+
+ export interface CommandArgvByName {
+ }
+
+ export class CommandReceiver {
+ private listenersByCommandName = new Map void>>()
+ private cleanUp: (() => void) | undefined = undefined
+
+ constructor(private componentCommandReceiver: RNComponentCommandReceiver, private tag: Tag) {
+ }
+
+ subscribe(commandName: TCommandName, listener: (argv: CommandArgvByName[TCommandName]) => void) {
+ if (!this.listenersByCommandName.has(commandName)) {
+ this.listenersByCommandName.set(commandName, new Set())
+ }
+ this.listenersByCommandName.get(commandName)!.add(listener)
+ const hasRegisteredCommandReceiver = !!this.cleanUp
+ if (!hasRegisteredCommandReceiver) {
+ this.cleanUp = this.componentCommandReceiver.registerCommandCallback(this.tag, (commandName: string, argv: any[]) => {
+ if (this.listenersByCommandName.has(commandName)) {
+ const listeners = this.listenersByCommandName.get(commandName)!
+ listeners.forEach(listener => {
+ listener(argv)
+ })
+ }
+ })
+ }
+
+ return () => {
+ this.listenersByCommandName.get(commandName)?.delete(listener)
+ if (this.listenersByCommandName.get(commandName)?.size ?? 0 === 0) {
+ this.listenersByCommandName.delete(commandName)
+ }
+ if (this.listenersByCommandName.size === 0) {
+ this.cleanUp?.()
+ }
+ }
+ }
+ }
+
+}
diff --git a/harmony/datetimepicker/src/main/ets/generated/components/ts.ts b/harmony/datetimepicker/src/main/ets/generated/components/ts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e63fbefb669e4d9af7e4a58837aa319883bc5c9e
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/generated/components/ts.ts
@@ -0,0 +1,5 @@
+/**
+ * This code was generated by "react-native codegen-lib-harmony"
+ */
+
+export * from "./RNDateTimePickerView"
diff --git a/harmony/datetimepicker/src/main/ets/generated/index.ets b/harmony/datetimepicker/src/main/ets/generated/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..041b7edf42bfd5af1779aa40009e5d5e53e2152f
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/generated/index.ets
@@ -0,0 +1,5 @@
+/**
+ * This code was generated by "react-native codegen-lib-harmony"
+ */
+
+export * from "./ts"
diff --git a/harmony/datetimepicker/src/main/ets/generated/ts.ts b/harmony/datetimepicker/src/main/ets/generated/ts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4c568a8e486aaafd28ba432cf802ae5277923d56
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/generated/ts.ts
@@ -0,0 +1,6 @@
+/**
+ * This code was generated by "react-native codegen-lib-harmony"
+ */
+
+export * as RNC from "./components/ts"
+export * as TM from "./turboModules/ts"
diff --git a/harmony/datetimepicker/src/main/ets/generated/turboModules/ts.ts b/harmony/datetimepicker/src/main/ets/generated/turboModules/ts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d1dae5612c329e2d338cb21936a3aadf279efcc5
--- /dev/null
+++ b/harmony/datetimepicker/src/main/ets/generated/turboModules/ts.ts
@@ -0,0 +1,5 @@
+
+/**
+ */
+
+export {}
diff --git a/harmony/datetimepicker/src/main/module.json5 b/harmony/datetimepicker/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..59f10ece5e2c645ce85898ddae46a83efb4ef048
--- /dev/null
+++ b/harmony/datetimepicker/src/main/module.json5
@@ -0,0 +1,9 @@
+{
+ "module": {
+ "name": "datetimepicker",
+ "type": "har",
+ "deviceTypes": [
+ "default"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/resources/base/element/color.json b/harmony/datetimepicker/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/harmony/datetimepicker/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/resources/base/element/string.json b/harmony/datetimepicker/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..247ebf721ac7685013e512ce248736d8470f7b74
--- /dev/null
+++ b/harmony/datetimepicker/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "Pager_viewAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "Pager_viewAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/resources/base/media/icon.png b/harmony/datetimepicker/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/harmony/datetimepicker/src/main/resources/base/media/icon.png differ
diff --git a/harmony/datetimepicker/src/main/resources/base/profile/main_pages.json b/harmony/datetimepicker/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/harmony/datetimepicker/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/harmony/datetimepicker/src/main/resources/en_US/element/string.json b/harmony/datetimepicker/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..247ebf721ac7685013e512ce248736d8470f7b74
--- /dev/null
+++ b/harmony/datetimepicker/src/main/resources/en_US/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "Pager_viewAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "Pager_viewAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/src/main/resources/zh_CN/element/string.json b/harmony/datetimepicker/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..4913f8801f001c17a7fb885deeb855f7dafccdb6
--- /dev/null
+++ b/harmony/datetimepicker/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "模块描述"
+ },
+ {
+ "name": "Pager_viewAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "Pager_viewAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/harmony/datetimepicker/ts.ts b/harmony/datetimepicker/ts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..14fcc6ee562499bc12ea08853545f0af7733341f
--- /dev/null
+++ b/harmony/datetimepicker/ts.ts
@@ -0,0 +1 @@
+export * from "./src/main/ets/RNDateTimePickerPackage";
\ No newline at end of file
diff --git a/package.json b/package.json
index e681cc785c99ca44b6c54e09fbd2984817011734..d3045d48b003d055a0154d041a6180d25da3cef0 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,10 @@
{
- "name": "@react-native-community/datetimepicker",
+ "name": "@react-native-ohos/datetimepicker",
"version": "7.6.2",
"description": "DateTimePicker component for React Native",
+ "harmony": {
+ "alias": "@react-native-community/datetimepicker"
+ },
"main": "./src/index.js",
"types": "src/index.d.ts",
"files": [
@@ -13,8 +16,9 @@
"!**/__mocks__"
],
"publishConfig": {
- "access": "public"
- },
+ "registry": "https://registry.npmjs.org/",
+ "access": "public"
+ },
"scripts": {
"start": "react-native start",
"start:android": "react-native run-android",
@@ -24,7 +28,8 @@
"bundle:ios": "mkdir -p example/dist && react-native bundle --platform ios --dev false --entry-file index.js --bundle-output example/dist/main.ios.jsbundle --assets-dest example/dist/assets",
"test": "jest",
"lint": "NODE_ENV=lint eslint {example,src,test}/**/*.js src/index.d.ts",
- "flow": "flow check"
+ "flow": "flow check",
+ "codegen-lib": "react-native codegen-lib-harmony --no-safety-check --npm-package-name datetimepicker --cpp-output-path ./harmony/datetimepicker/src/main/cpp/generated --ets-output-path ./harmony/datetimepicker/src/main/ets/generated --arkts-components-spec-paths ./src/specs/NativeComponentDateTimePicker.js"
},
"repository": {
"type": "git",
@@ -76,17 +81,11 @@
"react-native-test-app": "^2.5.32",
"react-native-windows": "^0.71.3",
"react-test-renderer": "18.2.0",
- "semantic-release": "^19.0.3"
+ "semantic-release": "^19.0.3",
+ "@rnoh/react-native-harmony-cli": "npm:@react-native-oh/react-native-harmony-cli@^0.0.27"
},
"dependencies": {
- "invariant": "^2.2.4"
- },
- "codegenConfig": {
- "name": "RNDateTimePickerCGen",
- "type": "all",
- "jsSrcsDir": "src/specs",
- "android": {
- "javaPackageName": "com.reactcommunity.rndatetimepicker"
- }
+ "invariant": "^2.2.4",
+ "@react-native-community/datetimepicker": "7.6.2"
}
}
diff --git a/patches/@react-native-segmented-control+segmented-control+2.4.0.patch b/patches/@react-native-segmented-control+segmented-control+2.4.0.patch
deleted file mode 100644
index 4b90fd02c0c8bb9e0bdc2c9d256a68dd9d0f2e4c..0000000000000000000000000000000000000000
--- a/patches/@react-native-segmented-control+segmented-control+2.4.0.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-diff --git a/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControl.js b/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControl.js
-index d82ecb5..7555b6a 100644
---- a/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControl.js
-+++ b/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControl.js
-@@ -92,6 +92,19 @@ const SegmentedControl = ({
- selectedIndex={selectedIndex}
- />
- )}
-+ {selectedIndex != null && segmentWidth ? (
-+
-+ ) : null}
-
- {values &&
- values.map((value, index) => {
-@@ -113,19 +126,7 @@ const SegmentedControl = ({
- );
- })}
-
-- {selectedIndex != null && segmentWidth ? (
--
-- ) : null}
-+
-
- );
- };
diff --git a/patches/detox+20.13.5.patch b/patches/detox+20.13.5.patch
deleted file mode 100644
index bb1e08222ce591f00fa1ee6a271ccafd7df18fb4..0000000000000000000000000000000000000000
--- a/patches/detox+20.13.5.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/node_modules/detox/src/devices/common/drivers/ios/tools/AppleSimUtils.js b/node_modules/detox/src/devices/common/drivers/ios/tools/AppleSimUtils.js
-index 06ce77e..c1f77f9 100644
---- a/node_modules/detox/src/devices/common/drivers/ios/tools/AppleSimUtils.js
-+++ b/node_modules/detox/src/devices/common/drivers/ios/tools/AppleSimUtils.js
-@@ -285,6 +285,7 @@ class AppleSimUtils {
- silent: true
- });
- } catch (err) {
-+
- // Since we have no convenient way to check whether the app is currently running or not, we might execute this
- // command (terminate) even if the app is not currently running, or even installed.
- // We have encountered some case where the following error is thrown in a case where the app did not run:
-@@ -295,9 +296,13 @@ class AppleSimUtils {
- // ```
- // This workaround is done to ignore the error above, as we do not care if the app was running before, we just
- // want to make sure it isn't now.
-+ const shouldBeIgnored = err.stderr.includes(`the app is not currently running`) ||
-+ err.stderr.includes(`found nothing to terminate`);
-+ console.log({customErr: err});
-+ console.log({customErrStderr: err.stderr});
-+ console.log({shouldBeIgnored, code: err.code, type: typeof err.code});
- if (err.code === 3 &&
-- (err.stderr.includes(`the app is not currently running`) ||
-- err.stderr.includes(`found nothing to terminate`))) {
-+ shouldBeIgnored) {
- return;
- }
-
diff --git a/src/DateTimePickerAndroid.android.js b/src/DateTimePickerAndroid.android.js
deleted file mode 100644
index 9b495114a85182fef9baa161df166034e7ed7231..0000000000000000000000000000000000000000
--- a/src/DateTimePickerAndroid.android.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-import {
- DATE_SET_ACTION,
- TIME_SET_ACTION,
- DISMISS_ACTION,
- NEUTRAL_BUTTON_ACTION,
- ANDROID_DISPLAY,
- ANDROID_MODE,
-} from './constants';
-import invariant from 'invariant';
-
-import type {AndroidNativeProps} from './types';
-import {getOpenPicker, validateAndroidProps} from './androidUtils';
-import pickers from './picker';
-import {
- createDateTimeSetEvtParams,
- createDismissEvtParams,
- createNeutralEvtParams,
-} from './eventCreators';
-import {processColor} from 'react-native';
-
-function open(props: AndroidNativeProps) {
- const {
- mode = ANDROID_MODE.date,
- display,
- value: originalValue,
- is24Hour,
- minimumDate,
- maximumDate,
- minuteInterval,
- timeZoneOffsetInMinutes,
- timeZoneName,
- onChange,
- onError,
- positiveButton,
- negativeButton,
- neutralButton,
- neutralButtonLabel,
- positiveButtonLabel,
- negativeButtonLabel,
- testID,
- } = props;
- validateAndroidProps(props);
- invariant(originalValue, 'A date or time must be specified as `value` prop.');
-
- const valueTimestamp = originalValue.getTime();
- const openPicker = getOpenPicker(mode);
-
- const presentPicker = async () => {
- try {
- const dialogButtons = {
- positive: {
- label: positiveButtonLabel,
- ...positiveButton,
- textColor: processColor(positiveButton?.textColor),
- },
- neutral: {
- label: neutralButtonLabel,
- ...neutralButton,
- textColor: processColor(neutralButton?.textColor),
- },
- negative: {
- label: negativeButtonLabel,
- ...negativeButton,
- textColor: processColor(negativeButton?.textColor),
- },
- };
-
- const displayOverride =
- display === ANDROID_DISPLAY.spinner
- ? ANDROID_DISPLAY.spinner
- : ANDROID_DISPLAY.default;
- const {action, timestamp, utcOffset} = await openPicker({
- value: valueTimestamp,
- display: displayOverride,
- is24Hour,
- minimumDate,
- maximumDate,
- minuteInterval,
- timeZoneOffsetInMinutes,
- timeZoneName,
- dialogButtons,
- testID,
- });
-
- switch (action) {
- case DATE_SET_ACTION:
- case TIME_SET_ACTION: {
- const date = new Date(timestamp);
- const [event] = createDateTimeSetEvtParams(date, utcOffset);
- onChange?.(event, date);
- break;
- }
-
- case NEUTRAL_BUTTON_ACTION: {
- const [event] = createNeutralEvtParams(originalValue, utcOffset);
- onChange?.(event, originalValue);
- break;
- }
- case DISMISS_ACTION:
- default: {
- const [event] = createDismissEvtParams(originalValue, utcOffset);
- onChange?.(event, originalValue);
- break;
- }
- }
- } catch (error) {
- onError && onError(error);
- }
- };
- presentPicker();
-}
-
-function dismiss(mode: AndroidNativeProps['mode']): Promise {
- // $FlowFixMe - `AbstractComponent` [1] is not an instance type.
- return pickers[mode].dismiss();
-}
-
-export const DateTimePickerAndroid = {open, dismiss};
diff --git a/src/DateTimePickerAndroid.js b/src/DateTimePickerAndroid.js
deleted file mode 100644
index ca4a5638b92e167a65f61f16a41b7998fa017fe1..0000000000000000000000000000000000000000
--- a/src/DateTimePickerAndroid.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-import {Platform} from 'react-native';
-
-const warn = () => {
- console.warn(`DateTimePickerAndroid is not supported on: ${Platform.OS}`);
-};
-
-export const DateTimePickerAndroid = {open: warn, dismiss: warn};
diff --git a/src/androidUtils.js b/src/androidUtils.js
deleted file mode 100644
index 9442cf6fdd4ab9704277e6fe79e0e65cafc5d60a..0000000000000000000000000000000000000000
--- a/src/androidUtils.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-import {ANDROID_DISPLAY, ANDROID_MODE} from './constants';
-import pickers from './picker';
-import type {AndroidNativeProps, DateTimePickerResult} from './types';
-import {sharedPropsValidation} from './utils';
-import invariant from 'invariant';
-import {processColor} from 'react-native';
-
-type Timestamp = number;
-
-type ProcessedButton = {
- title: string,
- textColor: $Call,
-};
-
-type OpenParams = {
- value: Timestamp,
- display: AndroidNativeProps['display'],
- is24Hour: AndroidNativeProps['is24Hour'],
- minimumDate: AndroidNativeProps['minimumDate'],
- maximumDate: AndroidNativeProps['maximumDate'],
- minuteInterval: AndroidNativeProps['minuteInterval'],
- timeZoneOffsetInMinutes: AndroidNativeProps['timeZoneOffsetInMinutes'],
- timeZoneName: AndroidNativeProps['timeZoneName'],
- testID: AndroidNativeProps['testID'],
- dialogButtons: {
- positive: ProcessedButton,
- negative: ProcessedButton,
- neutral: ProcessedButton,
- },
-};
-
-export type PresentPickerCallback =
- (OpenParams) => Promise;
-
-function getOpenPicker(
- mode: AndroidNativeProps['mode'],
-): PresentPickerCallback {
- switch (mode) {
- case ANDROID_MODE.time:
- return ({
- value,
- display,
- is24Hour,
- minuteInterval,
- timeZoneOffsetInMinutes,
- timeZoneName,
- dialogButtons,
- }: OpenParams) =>
- // $FlowFixMe - `AbstractComponent` [1] is not an instance type.
- pickers[mode].open({
- value,
- display,
- minuteInterval,
- is24Hour,
- timeZoneOffsetInMinutes,
- timeZoneName,
- dialogButtons,
- });
- default:
- return ({
- value,
- display,
- minimumDate,
- maximumDate,
- timeZoneOffsetInMinutes,
- timeZoneName,
- dialogButtons,
- testID,
- }: OpenParams) =>
- // $FlowFixMe - `AbstractComponent` [1] is not an instance type.
- pickers[ANDROID_MODE.date].open({
- value,
- display,
- minimumDate,
- maximumDate,
- timeZoneOffsetInMinutes,
- timeZoneName,
- dialogButtons,
- testID,
- });
- }
-}
-
-function validateAndroidProps(props: AndroidNativeProps) {
- sharedPropsValidation({value: props?.value});
- const {mode, display} = props;
- invariant(
- !(display === ANDROID_DISPLAY.calendar && mode === ANDROID_MODE.time) &&
- !(display === ANDROID_DISPLAY.clock && mode === ANDROID_MODE.date),
- `display: ${display} and mode: ${mode} cannot be used together.`,
- );
- if (
- props?.positiveButtonLabel !== undefined ||
- props?.negativeButtonLabel !== undefined ||
- props?.neutralButtonLabel !== undefined
- ) {
- console.warn(
- 'positiveButtonLabel, negativeButtonLabel and neutralButtonLabel are deprecated.' +
- 'Use positive / negative / neutralButton prop instead.',
- );
- }
-}
-export {getOpenPicker, validateAndroidProps};
diff --git a/src/constants.js b/src/constants.js
deleted file mode 100644
index acc91329611e7f06457b1417d17a5ff85d430fb6..0000000000000000000000000000000000000000
--- a/src/constants.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-export const MIN_MS = 60000;
-
-export const ANDROID_DISPLAY = Object.freeze({
- default: 'default',
- spinner: 'spinner',
-
- // NOTE: the following are exposed, but the native module instead uses "default"
- clock: 'clock',
- calendar: 'calendar',
-});
-
-export const EVENT_TYPE_SET = 'set';
-export const EVENT_TYPE_DISMISSED = 'dismissed';
-export const ANDROID_EVT_TYPE = Object.freeze({
- set: EVENT_TYPE_SET,
- dismissed: EVENT_TYPE_DISMISSED,
- neutralButtonPressed: 'neutralButtonPressed',
-});
-
-export const IOS_DISPLAY = Object.freeze({
- default: 'default',
- spinner: 'spinner',
- compact: 'compact',
- inline: 'inline',
-});
-
-const COMMON_MODES = Object.freeze({
- date: 'date',
- time: 'time',
-});
-
-export const ANDROID_MODE = COMMON_MODES;
-
-export const WINDOWS_MODE = COMMON_MODES;
-
-export const IOS_MODE = Object.freeze({
- ...COMMON_MODES,
- datetime: 'datetime',
- countdown: 'countdown',
-});
-
-export const DAY_OF_WEEK = Object.freeze({
- Sunday: 0,
- Monday: 1,
- Tuesday: 2,
- Wednesday: 3,
- Thursday: 4,
- Friday: 5,
- Saturday: 6,
-});
-
-export const DATE_SET_ACTION = 'dateSetAction';
-export const TIME_SET_ACTION = 'timeSetAction';
-export const DISMISS_ACTION = 'dismissedAction';
-
-export const NEUTRAL_BUTTON_ACTION = 'neutralButtonAction';
diff --git a/src/datepicker.android.js b/src/datepicker.android.js
deleted file mode 100644
index 5d5eadb68547565813c5aea6fca60a98b38c3583..0000000000000000000000000000000000000000
--- a/src/datepicker.android.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow strict-local
- */
-import {DATE_SET_ACTION, DISMISS_ACTION, ANDROID_DISPLAY} from './constants';
-import {toMilliseconds} from './utils';
-import RNDatePickerAndroid from './specs/NativeModuleDatePicker';
-import type {DatePickerOptions, DateTimePickerResult} from './types';
-
-export default class DatePickerAndroid {
- /**
- * Opens the standard Android date picker dialog.
- *
- * The available keys for the `options` object are:
- *
- * - `value` (`Date` object) - date to show by default
- * - `minimumDate` (`Date` object) - minimum date that can be selected
- * - `maximumDate` (`Date` object) - maximum date that can be selected
- * - `testID` (`string`) - Sets view tag for use with automation frameworks
- * - `display` (`enum('calendar', 'spinner', 'default')`) - To set the date-picker display to calendar/spinner/default
- * - 'calendar': Show a date picker in calendar mode.
- * - 'spinner': Show a date picker in spinner mode.
- * - 'default': Show a default native date picker(spinner/calendar) based on android versions.
- *
- * Returns a Promise which will be invoked an object containing `action`, `year`, `month` (0-11),
- * `day` if the user picked a date. If the user dismissed the dialog, the Promise will
- * still be resolved with action being `DatePickerAndroid.dismissedAction` and all the other keys
- * being undefined. **Always** check whether the `action` before reading the values.
- *
- * Note the native date picker dialog has some UI glitches on Android 4 and lower
- * when using the `minimumDate` and `maximumDate` options.
- */
- static async open(options: DatePickerOptions): Promise {
- toMilliseconds(options, 'value', 'minimumDate', 'maximumDate');
- options.display = options.display || ANDROID_DISPLAY.default;
-
- return RNDatePickerAndroid.open(options);
- }
-
- static async dismiss(): Promise {
- return RNDatePickerAndroid.dismiss();
- }
-
- /**
- * A date has been selected.
- */
- static +dateSetAction: 'dateSetAction' = DATE_SET_ACTION;
- /**
- * The dialog has been dismissed.
- */
- static +dismissedAction: 'dismissedAction' = DISMISS_ACTION;
-}
diff --git a/src/datetimepicker.android.js b/src/datetimepicker.android.js
deleted file mode 100644
index c530d70ed26a8f1125698ae8e9f182e04789f520..0000000000000000000000000000000000000000
--- a/src/datetimepicker.android.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-import {ANDROID_DISPLAY, ANDROID_MODE} from './constants';
-import {useEffect} from 'react';
-
-import type {AndroidNativeProps} from './types';
-import {validateAndroidProps} from './androidUtils';
-import {DateTimePickerAndroid} from './DateTimePickerAndroid';
-
-export default function RNDateTimePickerAndroid(
- props: AndroidNativeProps,
-): null {
- validateAndroidProps(props);
- const {
- mode = ANDROID_MODE.date,
- display = ANDROID_DISPLAY.default,
- value,
- onChange,
- is24Hour,
- minimumDate,
- maximumDate,
- minuteInterval,
- onError,
- timeZoneOffsetInMinutes,
- timeZoneName,
- positiveButton,
- negativeButton,
- neutralButton,
- positiveButtonLabel,
- negativeButtonLabel,
- neutralButtonLabel,
- testID,
- } = props;
- const valueTimestamp = value.getTime();
-
- useEffect(() => {
- // This effect runs on unmount / with mode change, and will ensure the picker is closed.
- // This allows for controlling the opening state of the picker through declarative logic in jsx.
- return () => DateTimePickerAndroid.dismiss(mode);
- }, [mode]);
-
- useEffect(
- function showOrUpdatePicker() {
- const params = {
- mode,
- value: new Date(valueTimestamp),
- display,
- is24Hour,
- minimumDate,
- maximumDate,
- minuteInterval,
- timeZoneOffsetInMinutes,
- timeZoneName,
- onError,
- onChange,
- positiveButton,
- negativeButton,
- neutralButton,
- positiveButtonLabel,
- negativeButtonLabel,
- neutralButtonLabel,
- testID,
- };
- DateTimePickerAndroid.open(params);
- },
- // the android dialog, when presented, will actually ignore updates to all props other than `value`
- // as an alternative, use the DateTimePickerAndroid whose reason for existence is described in
- // https://github.com/react-native-datetimepicker/datetimepicker/pull/327#issuecomment-723160992
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [onChange, valueTimestamp, mode],
- );
-
- return null;
-}
diff --git a/src/datetimepicker.ios.js b/src/datetimepicker.harmony.js
similarity index 46%
rename from src/datetimepicker.ios.js
rename to src/datetimepicker.harmony.js
index e040136b54f48f9c2f8e4716506cbcb29c4957d7..0e0ae2b081fc7f34fd3053b9722e772ea1a8fac0 100644
--- a/src/datetimepicker.ios.js
+++ b/src/datetimepicker.harmony.js
@@ -1,47 +1,59 @@
/**
- * Copyright (c) Facebook, Inc. and its affiliates.
+ * MIT License
*
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
+ * Copyright (C) 2023 Huawei Device Co., Ltd.
*
- * This is a controlled component version of RNDateTimePicker
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
*
- * @format
- * @flow strict-local
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
*/
import RNDateTimePicker from './picker';
-import {dateToMilliseconds, sharedPropsValidation} from './utils';
+import {dateToMilliseconds, sharedPropsValidation} from '@react-native-community/datetimepicker/src/utils';
import {
IOS_DISPLAY,
EVENT_TYPE_SET,
EVENT_TYPE_DISMISSED,
IOS_MODE,
-} from './constants';
+} from '@react-native-community/datetimepicker/src/constants';
import * as React from 'react';
-import {Platform} from 'react-native';
+import {processColor} from 'react-native';
import type {
DateTimePickerEvent,
NativeEventIOS,
IOSNativeProps,
IOSDisplay,
-} from './types';
-
-const getDisplaySafe = (display: IOSDisplay): IOSDisplay => {
- const majorVersionIOS = parseInt(Platform.Version, 10);
- if (display === IOS_DISPLAY.inline && majorVersionIOS < 14) {
- // inline is available since 14.0
- return IOS_DISPLAY.spinner;
- }
- if (majorVersionIOS < 14) {
- // NOTE this should compare against 13.4, not 14 according to https://developer.apple.com/documentation/uikit/uidatepickerstyle/uidatepickerstylecompact?changes=latest_minor&language=objc
- // but UIDatePickerStyleCompact does not seem to work prior to 14
- // only the spinner display (UIDatePickerStyleWheels) is thus available below 14
- return IOS_DISPLAY.spinner;
- }
+} from '@react-native-community/datetimepicker/src/types';
- return display;
-};
+// const getDisplaySafe = (display: IOSDisplay): IOSDisplay=>{
+// const majorVersionIOS = parseInt(Platfrom.Version, 10);
+// if(display === IOS_DISPLAY.inline && majorVersionIOS < 14){
+// // inline is available since 14.0
+// return IOS_DISPLAY.spinner;
+// }
+// if(majorVersionIOS < 14){
+// // NOTE this should compare against 13.4, not 14 according to https://developer.apple.com/documentation/uikit/uidatepickerstyle/uidatepickerstylecompact?changes=latest_minor&language=objc
+// // but UIDatePickerStyleCompact does not seem to work prior to 14
+// // only the spinner display (UIDatePickerStyleWheels) is thus available below 14
+// return IOS_DISPLAY.spinner;
+// }
+//
+// return display
+// }
export default function Picker({
value,
@@ -58,11 +70,13 @@ export default function Picker({
mode = IOS_MODE.date,
display: providedDisplay = IOS_DISPLAY.default,
disabled = false,
+ is24Hour = true,
...other
}: IOSNativeProps): React.Node {
sharedPropsValidation({value, timeZoneOffsetInMinutes, timeZoneName});
- const display = getDisplaySafe(providedDisplay);
+ // const display = getDisplaySafe(providedDisplay)
+ const display = providedDisplay;
const _onChange = (event: NativeEventIOS) => {
const timestamp = event.nativeEvent.timestamp;
@@ -104,13 +118,14 @@ export default function Picker({
timeZoneName={timeZoneName}
onChange={_onChange}
onPickerDismiss={onDismiss}
- textColor={textColor}
- accentColor={accentColor}
+ textColor={processColor(textColor)}
+ accentColor={processColor(accentColor)}
themeVariant={themeVariant}
onStartShouldSetResponder={() => true}
onResponderTerminationRequest={() => false}
displayIOS={display}
enabled={disabled !== true}
+ is24Hour={is24Hour}
/>
);
}
diff --git a/src/datetimepicker.js b/src/datetimepicker.js
deleted file mode 100644
index c3506070761467f3381d84111e8298292847d20e..0000000000000000000000000000000000000000
--- a/src/datetimepicker.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-
-import React from 'react';
-import {Platform} from 'react-native';
-
-import type {BaseProps} from './types';
-
-export default function DateTimePicker(_props: BaseProps): null {
- React.useEffect(() => {
- console.warn(`DateTimePicker is not supported on: ${Platform.OS}`);
- }, []);
- return null;
-}
diff --git a/src/datetimepicker.windows.js b/src/datetimepicker.windows.js
deleted file mode 100644
index b008503ddcbf9b448efc7851c9240dedec1d7f46..0000000000000000000000000000000000000000
--- a/src/datetimepicker.windows.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License.
- * @format
- * @flow strict-local
- */
-'use strict';
-
-import {
- type HostComponent,
- requireNativeComponent,
- StyleSheet,
-} from 'react-native';
-import type {
- WindowsNativeProps,
- WindowsDatePickerChangeEvent,
- DateTimePickerEvent,
-} from './types';
-import * as React from 'react';
-import {EVENT_TYPE_SET, WINDOWS_MODE} from './constants';
-import {sharedPropsValidation} from './utils';
-
-const styles = StyleSheet.create({
- rnDatePicker: {
- height: 32,
- width: 150,
- },
-});
-
-// $FlowExpectedError - this export is used in tests only, so don't care
-export const RNDateTimePickerWindows = requireNativeComponent(
- 'RNDateTimePickerWindows',
-);
-const RNTimePickerWindows = requireNativeComponent('RNTimePickerWindows');
-
-export default function RNDateTimePickerQWE(
- props: WindowsNativeProps,
-): React.Node {
- sharedPropsValidation({value: props?.value});
-
- const localProps = {
- accessibilityLabel: props.accessibilityLabel,
- dayOfWeekFormat: props.dayOfWeekFormat,
- dateFormat: props.dateFormat,
- firstDayOfWeek: props.firstDayOfWeek,
- maxDate: props.maximumDate ? props.maximumDate.getTime() : undefined, // time in milliseconds
- minDate: props.minimumDate ? props.minimumDate.getTime() : undefined, // time in milliseconds
- onChange: props.onChange,
- placeholderText: props.placeholderText,
- selectedDate: props.value ? props.value.getTime() : undefined, // time in milliseconds
- style: [styles.rnDatePicker, props.style],
- };
-
- const _onChange = (event: WindowsDatePickerChangeEvent) => {
- const {onChange} = props;
- const unifiedEvent: DateTimePickerEvent = {
- ...event,
- nativeEvent: {
- ...event.nativeEvent,
- timestamp: event.nativeEvent.newDate,
- utcOffset: 0,
- },
- type: EVENT_TYPE_SET,
- };
-
- onChange && onChange(unifiedEvent, new Date(event.nativeEvent.newDate));
- };
-
- const timezoneOffsetInSeconds = (() => {
- // The Date object returns timezone in minutes. Convert that to seconds
- // and multiply by -1 so that the offset can be added to UTC+0 time to get
- // the correct value on the native side.
- if (timezoneOffsetInSeconds == null && props.value != null) {
- return -60 * props.value.getTimezoneOffset();
- }
- return props.timeZoneOffsetInSeconds;
- })();
- const {mode} = props;
-
- // 'date' is the default mode
- if (mode === WINDOWS_MODE.date || mode == null) {
- return (
-
- );
- } else if (mode === WINDOWS_MODE.time) {
- return (
-
- );
- } else {
- console.error(`RNDateTimePicker: unknown mode ${mode}`);
- return null;
- }
-}
diff --git a/src/eventCreators.js b/src/eventCreators.js
deleted file mode 100644
index cd16fbd9ecc4227893236ab41cc82a65e2d113bf..0000000000000000000000000000000000000000
--- a/src/eventCreators.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @flow strict-local
- */
-import type {DateTimePickerEvent} from './types';
-import {ANDROID_EVT_TYPE, EVENT_TYPE_SET} from './constants';
-
-export const createDateTimeSetEvtParams = (
- date: Date,
- utcOffset: number,
-): [DateTimePickerEvent, Date] => {
- return [
- {
- type: EVENT_TYPE_SET,
- nativeEvent: {
- timestamp: date.getTime(),
- utcOffset,
- },
- },
- date,
- ];
-};
-
-export const createDismissEvtParams = (
- date: Date,
- utcOffset: number,
-): [DateTimePickerEvent, Date] => {
- return [
- {
- type: ANDROID_EVT_TYPE.dismissed,
- nativeEvent: {
- timestamp: date.getTime(),
- utcOffset,
- },
- },
- date,
- ];
-};
-
-export const createNeutralEvtParams = (
- date: Date,
- utcOffset: number,
-): [DateTimePickerEvent, Date] => {
- return [
- {
- type: ANDROID_EVT_TYPE.neutralButtonPressed,
- nativeEvent: {
- timestamp: date.getTime(),
- utcOffset,
- },
- },
- date,
- ];
-};
diff --git a/src/index.d.ts b/src/index.d.ts
index a3c346ad8ef8afcb71255417a29b81e3aa96ecd4..3a4fe0f7151a3c77dd769226aa14d3a034dd8350 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -225,4 +225,4 @@ declare const RNDateTimePicker: FC<
>;
export default RNDateTimePicker;
-export const DateTimePickerAndroid: typeof DateTimePickerAndroidType;
+export const DateTimePickerAndroid: typeof DateTimePickerAndroidType;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index ca4ff8827fae2e8665f33fc5bfb246eedd7f9b0b..00d84f048504ac77a191b7600da5e822e968069c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,7 +3,7 @@
* @flow strict-local
*/
import RNDateTimePicker from './datetimepicker';
-export * from './eventCreators';
-export {DateTimePickerAndroid} from './DateTimePickerAndroid';
+export * from '@react-native-community/datetimepicker/src/eventCreators';
+export {DateTimePickerAndroid} from '@react-native-community/datetimepicker/src/DateTimePickerAndroid';
export default RNDateTimePicker;
diff --git a/src/picker.android.js b/src/picker.android.js
deleted file mode 100644
index 4e29a58c31ccac518ff6d399b2710359a8a3b7ce..0000000000000000000000000000000000000000
--- a/src/picker.android.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-import DatePickerAndroid from './datepicker';
-import TimePickerAndroid from './timepicker';
-import {ANDROID_MODE} from './constants';
-
-const pickers = {
- [ANDROID_MODE.date]: DatePickerAndroid,
- [ANDROID_MODE.time]: TimePickerAndroid,
-};
-
-export default pickers;
diff --git a/src/picker.harmony.js b/src/picker.harmony.js
new file mode 100644
index 0000000000000000000000000000000000000000..1a98704bb4825f8ed585a38bcbfa245adc0064e7
--- /dev/null
+++ b/src/picker.harmony.js
@@ -0,0 +1,26 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2023 Huawei Device Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+import RNDateTimePicker from './specs/NativeComponentDateTimePicker';
+
+export default RNDateTimePicker;
diff --git a/src/picker.ios.js b/src/picker.ios.js
deleted file mode 100644
index c87d8e5f1a35607442e96ef27900d2148754528f..0000000000000000000000000000000000000000
--- a/src/picker.ios.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow strict-local
- */
-import RNDateTimePicker from './specs/NativeComponentDateTimePicker';
-
-export default RNDateTimePicker;
diff --git a/src/picker.windows.js b/src/picker.windows.js
deleted file mode 100644
index 56a103c38a9396537d1d032d24b070c7389c31d3..0000000000000000000000000000000000000000
--- a/src/picker.windows.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow strict-local
- */
-import {requireNativeComponent} from 'react-native';
-
-export default (requireNativeComponent(
- 'RNDateTimePickerWindows',
- // $FlowFixMe Flow: Unclear type. Using `any`, `Object`, or `Function` types is not safe!
-): any);
diff --git a/src/specs/NativeComponentDateTimePicker.js b/src/specs/NativeComponentDateTimePicker.js
index 526dbc8f15f70d9e62c32dcf9ac22b2618f816ff..dd4d4bff146dc3d3a78f0df058aec8b2d7a9ed1a 100644
--- a/src/specs/NativeComponentDateTimePicker.js
+++ b/src/specs/NativeComponentDateTimePicker.js
@@ -1,7 +1,7 @@
// @flow strict-local
-import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
-import type {ColorValue} from 'react-native/Libraries/StyleSheet/StyleSheet';
-import type {HostComponent} from 'react-native';
+import type { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes';
+import type { ColorValue } from 'react-native/Libraries/StyleSheet/StyleSheet';
+import type { HostComponent, ProcessedColorValue } from 'react-native';
import type {
BubblingEventHandler,
@@ -28,16 +28,17 @@ type NativeProps = $ReadOnly<{|
mode?: WithDefault<'date' | 'time' | 'datetime' | 'countdown', 'date'>,
timeZoneOffsetInMinutes?: ?Double,
timeZoneName?: ?string,
- textColor?: ?ColorValue,
- accentColor?: ?ColorValue,
+ textColor?: ?ProcessedColorValue,
+ accentColor?: ?ProcessedColorValue,
themeVariant?: WithDefault<'dark' | 'light' | 'unspecified', 'unspecified'>,
displayIOS?: WithDefault<
'default' | 'spinner' | 'compact' | 'inline',
'default',
>,
+ is24Hour?: WithDefault,
enabled?: WithDefault,
|}>;
-export default (codegenNativeComponent('RNDateTimePicker', {
+export default (codegenNativeComponent('RNDateTimePickerView', {
excludedPlatforms: ['android'],
}): HostComponent);
diff --git a/src/specs/NativeModuleDatePicker.js b/src/specs/NativeModuleDatePicker.js
deleted file mode 100644
index f53d972963312dc8f748bed384e7ba001790eca5..0000000000000000000000000000000000000000
--- a/src/specs/NativeModuleDatePicker.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// @flow strict-local
-
-import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
-import {TurboModuleRegistry} from 'react-native';
-import type {DateTimePickerResult} from '../types';
-
-type OpenParams = $ReadOnly<{|
- // TODO does codegen handle object type?
-|}>;
-export interface Spec extends TurboModule {
- dismiss(): Promise;
- open(params: OpenParams): Promise;
-}
-
-export default (TurboModuleRegistry.getEnforcing('RNCDatePicker'): ?Spec);
diff --git a/src/specs/NativeModuleTimePicker.js b/src/specs/NativeModuleTimePicker.js
deleted file mode 100644
index 23c0cdb6bbb39a11d45288d9370d3a223933d85b..0000000000000000000000000000000000000000
--- a/src/specs/NativeModuleTimePicker.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// @flow strict-local
-
-import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
-import {TurboModuleRegistry} from 'react-native';
-import type {DateTimePickerResult} from '../types';
-
-type OpenParams = $ReadOnly<{|
- // TODO does codegen handle object type?
-|}>;
-
-export interface Spec extends TurboModule {
- dismiss(): Promise;
- open(params: OpenParams): Promise;
-}
-
-export default (TurboModuleRegistry.getEnforcing('RNCTimePicker'): ?Spec);
diff --git a/src/timepicker.android.js b/src/timepicker.android.js
deleted file mode 100644
index 8c7a050c2de1ff3697e4af7544e9832ba119be7b..0000000000000000000000000000000000000000
--- a/src/timepicker.android.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow strict-local
- */
-import {TIME_SET_ACTION, DISMISS_ACTION, ANDROID_DISPLAY} from './constants';
-import {toMilliseconds} from './utils';
-import RNTimePickerAndroid from './specs/NativeModuleTimePicker';
-import type {TimePickerOptions, DateTimePickerResult} from './types';
-
-export default class TimePickerAndroid {
- /**
- * Opens the standard Android time picker dialog.
- *
- * The available keys for the `options` object are:
- * - `value` (`Date` object) - date to show by default
- * * `is24Hour` (boolean) - If `true`, the picker uses the 24-hour format. If `false`,
- * the picker shows an AM/PM chooser. If undefined, the default for the current locale
- * is used.
- * * `minuteInterval` (enum(1 | 5 | 10 | 15 | 20 | 30)`) - set the time picker minutes' interval
- * * `mode` (`enum('clock', 'spinner', 'default')`) - set the time picker mode
- * - 'clock': Show a time picker in clock mode.
- * - 'spinner': Show a time picker in spinner mode.
- * - 'default': Show a default time picker based on Android versions.
- *
- * Returns a Promise which will be invoked an object containing `action`, `hour` (0-23),
- * `minute` (0-59) if the user picked a time. If the user dismissed the dialog, the Promise will
- * still be resolved with action being `TimePickerAndroid.dismissedAction` and all the other keys
- * being undefined. **Always** check whether the `action` before reading the values.
- */
- static async open(options: TimePickerOptions): Promise {
- toMilliseconds(options, 'value');
- options.display = options.display || ANDROID_DISPLAY.default;
- return RNTimePickerAndroid.open(options);
- }
-
- static async dismiss(): Promise {
- return RNTimePickerAndroid.dismiss();
- }
-
- /**
- * A time has been selected.
- */
- static +timeSetAction: 'timeSetAction' = TIME_SET_ACTION;
- /**
- * The dialog has been dismissed.
- */
- static +dismissedAction: 'dismissedAction' = DISMISS_ACTION;
-}
diff --git a/src/types.js b/src/types.js
deleted file mode 100644
index 521c1f82900b41bf40e7ed65e03cb5c93387f023..0000000000000000000000000000000000000000
--- a/src/types.js
+++ /dev/null
@@ -1,258 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-
-import type {SyntheticEvent} from 'react-native/Libraries/Types/CoreEventTypes';
-import type {HostComponent} from 'react-native';
-import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
-import type {ElementRef, Node} from 'react';
-import type {ColorValue} from 'react-native/Libraries/StyleSheet/StyleSheet';
-import {
- ANDROID_MODE,
- ANDROID_DISPLAY,
- DAY_OF_WEEK,
- IOS_DISPLAY,
- IOS_MODE,
- WINDOWS_MODE,
- ANDROID_EVT_TYPE,
-} from './constants';
-
-export type IOSDisplay = $Keys;
-export type IOSMode = $Keys;
-type AndroidMode = $Keys;
-type WindowsMode = $Keys;
-type Display = $Keys;
-type AndroidEvtTypes = $Keys;
-type MinuteInterval = ?(1 | 2 | 3 | 4 | 5 | 6 | 10 | 12 | 15 | 20 | 30);
-
-export type NativeEventIOS = SyntheticEvent<
- $ReadOnly<{|
- timestamp: number,
- utcOffset: number,
- |}>,
->;
-
-export type DateTimePickerEvent = {
- type: AndroidEvtTypes,
- nativeEvent: $ReadOnly<{
- timestamp: number,
- utcOffset: number,
- ...
- }>,
- ...
-};
-
-type BaseOptions = {|
- /**
- * The currently selected date.
- */
- value: Date,
-
- /**
- * change handler.
- *
- * This is called when the user changes the date or time in the UI.
- * Or when they clear / dismiss the dialog.
- * The first argument is an Event, the second a selected Date.
- */
- onChange?: ?(event: DateTimePickerEvent, date?: Date) => void,
-|};
-
-type DateOptions = {|
- ...BaseOptions,
-
- /**
- * Maximum date.
- *
- * Restricts the range of possible date/time values.
- */
- maximumDate?: ?Date,
-
- /**
- * Minimum date.
- *
- * Restricts the range of possible date/time values.
- */
- minimumDate?: ?Date,
-|};
-
-type TimeOptions = $ReadOnly<{|
- ...BaseOptions,
-
- /**
- * Display TimePicker in 24 hour.
- */
- is24Hour?: ?boolean,
-|}>;
-
-type ViewPropsWithoutChildren = $Diff<
- ViewProps,
- {children: ViewProps['children']},
->;
-
-export type BaseProps = $ReadOnly<{|
- ...ViewPropsWithoutChildren,
- ...DateOptions,
- /**
- * Timezone in database name.
- *
- * By default, the date picker will use the device's timezone. With this
- * parameter, it is possible to force a certain timezone based on IANA
- */
- timeZoneName?: ?string,
-|}>;
-
-export type IOSNativeProps = $ReadOnly<{|
- ...BaseProps,
-
- /**
- * The date picker locale.
- */
- locale?: ?string,
-
- /**
- * The interval at which minutes can be selected.
- */
- minuteInterval?: MinuteInterval,
-
- /**
- * The date picker mode.
- */
- mode?: IOSMode,
-
- /**
- * Timezone offset in minutes.
- *
- * By default, the date picker will use the device's timezone. With this
- * parameter, it is possible to force a certain timezone offset. For
- * instance, to show times in Pacific Standard Time, pass -7 * 60.
- */
- timeZoneOffsetInMinutes?: ?number,
-
- /**
- * The date picker text color.
- */
- textColor?: ?ColorValue,
-
- /**
- * The date picker accent color.
- *
- * Sets the color of the selected, date and navigation icons.
- * Has no effect for display 'spinner'.
- */
- accentColor?: ?ColorValue,
-
- /**
- * Override theme variant used by iOS native picker
- */
- themeVariant?: 'dark' | 'light',
-
- /**
- * Sets the preferredDatePickerStyle for picker
- */
- display?: IOSDisplay,
-
- /**
- * Is this picker enabled?
- */
- enabled?: boolean,
-|}>;
-
-export type ButtonType = {label?: string, textColor?: ColorValue};
-
-export type AndroidNativeProps = $ReadOnly<{|
- ...BaseProps,
- ...DateOptions,
- ...TimeOptions,
-
- /**
- * The date picker mode.
- */
- mode: AndroidMode,
-
- /**
- * The display options.
- */
- display: Display,
-
- /**
- * Timezone offset in minutes.
- *
- * By default, the date picker will use the device's timezone. With this
- * parameter, it is possible to force a certain timezone offset. For
- * instance, to show times in Pacific Standard Time, pass -7 * 60.
- */
- timeZoneOffsetInMinutes?: ?number,
-
- /**
- * The interval at which minutes can be selected.
- */
- minuteInterval?: MinuteInterval,
-
- positiveButton?: ButtonType,
- neutralButton?: ButtonType,
- negativeButton?: ButtonType,
- /**
- * @deprecated use neutralButton instead
- * */
- neutralButtonLabel?: string,
- /**
- * @deprecated use positiveButton instead
- * */
- positiveButtonLabel?: string,
- /**
- * @deprecated use negativeButton instead
- * */
- negativeButtonLabel?: string,
- onError?: (Error) => void,
-|}>;
-
-export type DatePickerOptions = {|
- ...DateOptions,
- display?: Display,
-|};
-
-export type TimePickerOptions = {|
- ...TimeOptions,
- minuteInterval?: MinuteInterval,
- display?: Display,
-|};
-
-export type DateTimePickerResult = $ReadOnly<{|
- action: 'timeSetAction' | 'dateSetAction' | 'dismissedAction',
- timestamp: number,
- utcOffset: number,
-|}>;
-
-export type RCTDateTimePickerNative = Class>;
-export type NativeRef = {
- current: ElementRef | null,
-};
-
-export type WindowsDatePickerChangeEvent = {|
- nativeEvent: {|
- newDate: number,
- |},
-|};
-
-export type WindowsNativeProps = $ReadOnly<{|
- ...BaseProps,
- mode: WindowsMode,
-
- placeholderText?: string,
- dateFormat?:
- | 'day month year'
- | 'dayofweek day month'
- | 'longdate'
- | 'shortdate',
- dayOfWeekFormat?:
- | '{dayofweek.abbreviated(2)}'
- | '{dayofweek.abbreviated(3)}'
- | '{dayofweek.full}',
- firstDayOfWeek?: typeof DAY_OF_WEEK,
- timeZoneOffsetInSeconds?: number,
- is24Hour?: boolean,
- minuteInterval?: number,
- accessibilityLabel?: string,
-|}>;
diff --git a/src/utils.js b/src/utils.js
deleted file mode 100644
index a4dee188af39f32f2d67ff577f2e465926900057..0000000000000000000000000000000000000000
--- a/src/utils.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @format
- * @flow strict-local
- */
-import type {DatePickerOptions, TimePickerOptions} from './types';
-import invariant from 'invariant';
-
-/**
- * Convert a Date to a timestamp.
- */
-export function toMilliseconds(
- options: DatePickerOptions | TimePickerOptions,
- ...keys: Array
-) {
- keys.forEach(function each(key) {
- const value = options[key];
-
- // Is it a valid Date object?
- // $FlowFixMe: Cannot get `Object.prototype.toString` because property `toString` [1] cannot be unbound from the context [2] where it was defined.
- if (Object.prototype.toString.call(value) === '[object Date]') {
- options[key] = value.getTime();
- }
- });
-}
-
-export function dateToMilliseconds(date: ?Date): ?number {
- if (!date) {
- return;
- }
- return date.getTime();
-}
-
-export function sharedPropsValidation({
- value,
- timeZoneName,
- timeZoneOffsetInMinutes,
-}: {
- value: Date,
- timeZoneName?: ?string,
- timeZoneOffsetInMinutes?: ?number,
-}) {
- invariant(value, 'A date or time must be specified as `value` prop');
- invariant(
- value instanceof Date,
- '`value` prop must be an instance of Date object',
- );
- invariant(
- timeZoneName == null || timeZoneOffsetInMinutes == null,
- '`timeZoneName` and `timeZoneOffsetInMinutes` cannot be specified at the same time',
- );
- if (timeZoneOffsetInMinutes !== undefined) {
- console.warn(
- '`timeZoneOffsetInMinutes` is deprecated and will be removed in a future release. Use `timeZoneName` instead.',
- );
- }
-}