Integrate Picker into Fabric on Android
Summary: In this diff we integrate the Picker component on Android in Fabric. Since both AndroidDropdownPickerNativeComponent and AndroidDialogPickerNativeComponent use `style?: ?TextStyleProp`, which is not supported by the JS codegen, I had to handwrite the C++ files and check them in. The component is not fully functional yet because `setNativeProps` is not supported in Fabric. I will fix this in the next diff. Changelog: [Android] [Added] - Integrate Picker into Fabric on Android Reviewed By: mdvacca Differential Revision: D17954435 fbshipit-source-id: 6b7b029ab0c84c27a48c7dddd66878c9dea324bf
This commit is contained in:
Родитель
28a3b25c31
Коммит
9ff090e507
|
@ -0,0 +1,96 @@
|
|||
load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_debug_preprocessor_flags")
|
||||
load(
|
||||
"//tools/build_defs/oss:rn_defs.bzl",
|
||||
"ANDROID",
|
||||
"APPLE",
|
||||
"CXX",
|
||||
"YOGA_CXX_TARGET",
|
||||
"fb_xplat_cxx_test",
|
||||
"get_apple_compiler_flags",
|
||||
"get_apple_inspector_flags",
|
||||
"react_native_target",
|
||||
"react_native_xplat_target",
|
||||
"rn_xplat_cxx_library",
|
||||
"subdir_glob",
|
||||
)
|
||||
|
||||
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
|
||||
|
||||
rn_xplat_cxx_library(
|
||||
name = "androidpicker",
|
||||
srcs = glob(
|
||||
["**/*.cpp"],
|
||||
exclude = glob(["tests/**/*.cpp"]),
|
||||
),
|
||||
headers = glob(
|
||||
["**/*.h"],
|
||||
exclude = glob(["tests/**/*.h"]),
|
||||
),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob(
|
||||
[
|
||||
("", "*.h"),
|
||||
("androidpicker", "*.h"),
|
||||
],
|
||||
prefix = "react/components/androidpicker",
|
||||
),
|
||||
compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
"-std=c++14",
|
||||
"-Wall",
|
||||
],
|
||||
cxx_tests = [":tests"],
|
||||
fbandroid_deps = [
|
||||
react_native_target("jni/react/jni:jni"),
|
||||
],
|
||||
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
|
||||
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
|
||||
force_static = True,
|
||||
platforms = (ANDROID, APPLE, CXX),
|
||||
preprocessor_flags = [
|
||||
"-DLOG_TAG=\"ReactNative\"",
|
||||
"-DWITH_FBSYSTRACE=1",
|
||||
],
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
"fbsource//xplat/fbsystrace:fbsystrace",
|
||||
"fbsource//xplat/folly:headers_only",
|
||||
"fbsource//xplat/folly:memory",
|
||||
"fbsource//xplat/folly:molly",
|
||||
"fbsource//xplat/third-party/glog:glog",
|
||||
YOGA_CXX_TARGET,
|
||||
react_native_xplat_target("fabric/debug:debug"),
|
||||
react_native_xplat_target("fabric/core:core"),
|
||||
react_native_xplat_target("fabric/graphics:graphics"),
|
||||
react_native_xplat_target("fabric/components/view:view"),
|
||||
react_native_xplat_target("fabric/uimanager:uimanager"),
|
||||
"fbsource//xplat/js/react-native-github:generated_components-rncore",
|
||||
],
|
||||
)
|
||||
|
||||
fb_xplat_cxx_test(
|
||||
name = "tests",
|
||||
srcs = glob(["tests/**/*.cpp"]),
|
||||
headers = glob(["tests/**/*.h"]),
|
||||
compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
"-std=c++14",
|
||||
"-Wall",
|
||||
],
|
||||
contacts = ["oncall+react_native@xmail.facebook.com"],
|
||||
platforms = (
|
||||
# `Apple` and `Android` flavors are disabled because the module depends on `textlayoutmanager` which requires real an Emulator/Simulator to run.
|
||||
# At the same time, the code of tests does not rely on the simulator capabilities and it would be wasteful to add `fbandroid_use_instrumentation_test = True`.
|
||||
# (Beware of this option though.)
|
||||
# ANDROID,
|
||||
# APPLE,
|
||||
CXX
|
||||
),
|
||||
deps = [
|
||||
"fbsource//xplat/folly:molly",
|
||||
"fbsource//xplat/third-party/gmock:gtest",
|
||||
":androidpicker",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AndroidDialogPickerShadowNode.h"
|
||||
|
||||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using AndroidDialogPickerComponentDescriptor =
|
||||
ConcreteComponentDescriptor<AndroidDialogPickerShadowNode>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AndroidDialogPickerEventEmitter.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
void AndroidDialogPickerEventEmitter::onSelect(
|
||||
AndroidDialogPickerOnSelectStruct event) const {
|
||||
dispatchEvent("select", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "position", event.position);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/components/view/ViewEventEmitter.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct AndroidDialogPickerOnSelectStruct {
|
||||
int position;
|
||||
};
|
||||
|
||||
class AndroidDialogPickerEventEmitter : public ViewEventEmitter {
|
||||
public:
|
||||
using ViewEventEmitter::ViewEventEmitter;
|
||||
|
||||
void onSelect(AndroidDialogPickerOnSelectStruct value) const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AndroidDialogPickerProps.h"
|
||||
|
||||
#include <react/components/image/conversions.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
AndroidDialogPickerProps::AndroidDialogPickerProps(
|
||||
const AndroidDialogPickerProps &sourceProps,
|
||||
const RawProps &rawProps)
|
||||
: ViewProps(sourceProps, rawProps),
|
||||
color(convertRawProp(rawProps, "color", sourceProps.color, {})),
|
||||
enabled(convertRawProp(rawProps, "enabled", sourceProps.enabled, {true})),
|
||||
items(convertRawProp(rawProps, "items", sourceProps.items, {})),
|
||||
prompt(convertRawProp(rawProps, "prompt", sourceProps.prompt, {""})),
|
||||
selected(
|
||||
convertRawProp(rawProps, "selected", sourceProps.selected, {0})) {}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/components/view/ViewProps.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
#include <react/graphics/Color.h>
|
||||
#include <react/imagemanager/primitives.h>
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct AndroidDialogPickerItemsStruct {
|
||||
std::string label;
|
||||
int color;
|
||||
};
|
||||
|
||||
static inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
AndroidDialogPickerItemsStruct &result) {
|
||||
auto map = (better::map<std::string, RawValue>)value;
|
||||
|
||||
auto label = map.find("label");
|
||||
if (label != map.end()) {
|
||||
fromRawValue(label->second, result.label);
|
||||
}
|
||||
auto color = map.find("color");
|
||||
// C++ props are not used on Android at the moment, so we can leave
|
||||
// result.color uninitialized if the JS prop has a null value. TODO: revisit
|
||||
// this once we start using C++ props on Android.
|
||||
if (color != map.end() && color->second.hasValue()) {
|
||||
fromRawValue(color->second, result.color);
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string toString(
|
||||
const AndroidDialogPickerItemsStruct &value) {
|
||||
return "[Object AndroidDialogPickerItemsStruct]";
|
||||
}
|
||||
|
||||
static inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
std::vector<AndroidDialogPickerItemsStruct> &result) {
|
||||
auto items = (std::vector<RawValue>)value;
|
||||
for (const auto &item : items) {
|
||||
AndroidDialogPickerItemsStruct newItem;
|
||||
fromRawValue(item, newItem);
|
||||
result.emplace_back(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
class AndroidDialogPickerProps final : public ViewProps {
|
||||
public:
|
||||
AndroidDialogPickerProps() = default;
|
||||
|
||||
AndroidDialogPickerProps(
|
||||
const AndroidDialogPickerProps &sourceProps,
|
||||
const RawProps &rawProps);
|
||||
|
||||
#pragma mark - Props
|
||||
|
||||
const SharedColor color{};
|
||||
const bool enabled{true};
|
||||
const std::vector<AndroidDialogPickerItemsStruct> items{};
|
||||
const std::string prompt{""};
|
||||
const int selected{0};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AndroidDialogPickerShadowNode.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char AndroidDialogPickerComponentName[] = "AndroidDialogPicker";
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AndroidDialogPickerEventEmitter.h"
|
||||
#include "AndroidDialogPickerProps.h"
|
||||
|
||||
#include <react/components/view/ConcreteViewShadowNode.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char AndroidDialogPickerComponentName[];
|
||||
|
||||
/*
|
||||
* `ShadowNode` for <AndroidDialogPicker> component.
|
||||
*/
|
||||
using AndroidDialogPickerShadowNode = ConcreteViewShadowNode<
|
||||
AndroidDialogPickerComponentName,
|
||||
AndroidDialogPickerProps,
|
||||
AndroidDialogPickerEventEmitter>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AndroidDropdownPickerShadowNode.h"
|
||||
|
||||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using AndroidDropdownPickerComponentDescriptor =
|
||||
ConcreteComponentDescriptor<AndroidDropdownPickerShadowNode>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AndroidDropdownPickerEventEmitter.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
void AndroidDropdownPickerEventEmitter::onSelect(
|
||||
AndroidDropdownPickerOnSelectStruct event) const {
|
||||
dispatchEvent("select", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "position", event.position);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/components/view/ViewEventEmitter.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct AndroidDropdownPickerOnSelectStruct {
|
||||
int position;
|
||||
};
|
||||
|
||||
class AndroidDropdownPickerEventEmitter : public ViewEventEmitter {
|
||||
public:
|
||||
using ViewEventEmitter::ViewEventEmitter;
|
||||
|
||||
void onSelect(AndroidDropdownPickerOnSelectStruct value) const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AndroidDropdownPickerProps.h"
|
||||
|
||||
#include <react/components/image/conversions.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
AndroidDropdownPickerProps::AndroidDropdownPickerProps(
|
||||
const AndroidDropdownPickerProps &sourceProps,
|
||||
const RawProps &rawProps)
|
||||
: ViewProps(sourceProps, rawProps),
|
||||
color(convertRawProp(rawProps, "color", sourceProps.color, {})),
|
||||
enabled(convertRawProp(rawProps, "enabled", sourceProps.enabled, {true})),
|
||||
items(convertRawProp(rawProps, "items", sourceProps.items, {})),
|
||||
prompt(convertRawProp(rawProps, "prompt", sourceProps.prompt, {""})),
|
||||
selected(
|
||||
convertRawProp(rawProps, "selected", sourceProps.selected, {0})) {}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/components/view/ViewProps.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
#include <react/graphics/Color.h>
|
||||
#include <react/imagemanager/primitives.h>
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct AndroidDropdownPickerItemsStruct {
|
||||
std::string label;
|
||||
int color;
|
||||
};
|
||||
|
||||
static inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
AndroidDropdownPickerItemsStruct &result) {
|
||||
auto map = (better::map<std::string, RawValue>)value;
|
||||
|
||||
auto label = map.find("label");
|
||||
if (label != map.end()) {
|
||||
fromRawValue(label->second, result.label);
|
||||
}
|
||||
auto color = map.find("color");
|
||||
// C++ props are not used on Android at the moment, so we can leave
|
||||
// result.color uninitialized if the JS prop has a null value. TODO: revisit
|
||||
// this once we start using C++ props on Android.
|
||||
if (color != map.end() && color->second.hasValue()) {
|
||||
fromRawValue(color->second, result.color);
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string toString(
|
||||
const AndroidDropdownPickerItemsStruct &value) {
|
||||
return "[Object AndroidDropdownPickerItemsStruct]";
|
||||
}
|
||||
|
||||
static inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
std::vector<AndroidDropdownPickerItemsStruct> &result) {
|
||||
auto items = (std::vector<RawValue>)value;
|
||||
for (const auto &item : items) {
|
||||
AndroidDropdownPickerItemsStruct newItem;
|
||||
fromRawValue(item, newItem);
|
||||
result.emplace_back(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
class AndroidDropdownPickerProps final : public ViewProps {
|
||||
public:
|
||||
AndroidDropdownPickerProps() = default;
|
||||
|
||||
AndroidDropdownPickerProps(
|
||||
const AndroidDropdownPickerProps &sourceProps,
|
||||
const RawProps &rawProps);
|
||||
|
||||
#pragma mark - Props
|
||||
|
||||
const SharedColor color{};
|
||||
const bool enabled{true};
|
||||
const std::vector<AndroidDropdownPickerItemsStruct> items{};
|
||||
const std::string prompt{""};
|
||||
const int selected{0};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AndroidDropdownPickerShadowNode.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char AndroidDropdownPickerComponentName[] =
|
||||
"AndroidDropdownPicker";
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AndroidDropdownPickerEventEmitter.h"
|
||||
#include "AndroidDropdownPickerProps.h"
|
||||
|
||||
#include <react/components/view/ConcreteViewShadowNode.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char AndroidDropdownPickerComponentName[];
|
||||
|
||||
/*
|
||||
* `ShadowNode` for <AndroidDropdownPicker> component.
|
||||
*/
|
||||
using AndroidDropdownPickerShadowNode = ConcreteViewShadowNode<
|
||||
AndroidDropdownPickerComponentName,
|
||||
AndroidDropdownPickerProps,
|
||||
AndroidDropdownPickerEventEmitter>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Загрузка…
Ссылка в новой задаче