mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-06 07:06:11 +00:00
feat: use codegenNativeComponent to import native views (#1847)
Changed `requireNativeComponent` to `codegenNativeComponent` so that upcoming changes (Static View Configs, Bridgeless Mode and idk what more) in `react-native` are available in the library. Also, types and native components are now taken directly from `fabric` folder to make sure the values passed to the native components are the ones defined in props. It should work on all supported versions since `codegenNativeComponent` function exists from RN v. 0.61.0. Suggested by @RSNara and @cipolleschi Reason for [`5394bbb` (#1847)](5394bbbced): - on `Paper`, `Animated` uses `setNativeProps` method when we set `useNativeDriver` to `false`, and does not rerender the component. Therefore, new transform lands only in `SvgView` and is parsed in `RCTViewManager.m` . - on `Fabric`, the same code makes the components rerender. Due to this, information about new transform is passed to the `SvgView` child: `G` , making it apply translations from the transform in its `updateProps` method. - other than `Animated` use-case, on both archs, if we just passed `transform` prop to `Svg` component, it would end up in double transformations now as well. All of those changes are due to https://github.com/software-mansion/react-native-svg/pull/1895, which added proper parsing of RN style `transform` prop (array of transformations objects) therefore making `G` properly handle `transform` prop passed from `Svg`. Reason for [`19bcb24` (#1847)](19bcb2464b): Same as https://github.com/software-mansion/react-native-screens/pull/1624
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and 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/renderer/core/ConcreteComponentDescriptor.h>
|
||||
#include <react/renderer/imagemanager/ImageManager.h>
|
||||
#include <react/utils/ContextContainer.h>
|
||||
|
||||
#include "RNSVGImageShadowNode.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Descriptor for <RNSVGImage> component.
|
||||
*/
|
||||
class RNSVGImageComponentDescriptor final
|
||||
: public ConcreteComponentDescriptor<RNSVGImageShadowNode> {
|
||||
public:
|
||||
RNSVGImageComponentDescriptor(ComponentDescriptorParameters const ¶meters)
|
||||
: ConcreteComponentDescriptor(parameters),
|
||||
imageManager_(std::make_shared<ImageManager>(contextContainer_)){};
|
||||
|
||||
void adopt(ShadowNode::Unshared const &shadowNode) const override {
|
||||
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||
|
||||
auto imageShadowNode =
|
||||
std::static_pointer_cast<RNSVGImageShadowNode>(shadowNode);
|
||||
|
||||
// `RNSVGImageShadowNode` uses `ImageManager` to initiate image loading and
|
||||
// communicate the loading state and results to mounting layer.
|
||||
imageShadowNode->setImageManager(imageManager_);
|
||||
}
|
||||
|
||||
private:
|
||||
const SharedImageManager imageManager_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
|
||||
#include <react/renderer/core/LayoutContext.h>
|
||||
|
||||
#include "RNSVGImageShadowNode.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
const char RNSVGImageComponentName[] = "RNSVGImage";
|
||||
|
||||
void RNSVGImageShadowNode::setImageManager(
|
||||
const SharedImageManager &imageManager) {
|
||||
ensureUnsealed();
|
||||
imageManager_ = imageManager;
|
||||
}
|
||||
|
||||
ImageSource RNSVGImageShadowNode::getImageSource() const {
|
||||
auto source = getConcreteProps().src;
|
||||
|
||||
auto layoutMetrics = getLayoutMetrics();
|
||||
auto size = layoutMetrics.getContentFrame().size;
|
||||
auto scale = layoutMetrics.pointScaleFactor;
|
||||
source.size = size;
|
||||
source.scale = scale;
|
||||
return source;
|
||||
}
|
||||
|
||||
void RNSVGImageShadowNode::updateStateIfNeeded() {
|
||||
ensureUnsealed();
|
||||
|
||||
auto imageSource = getImageSource();
|
||||
auto const ¤tState = getStateData();
|
||||
bool hasSameImageSource = currentState.getImageSource() == imageSource;
|
||||
|
||||
if (hasSameImageSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto state = RNSVGImageState{
|
||||
imageSource,
|
||||
imageManager_->requestImage(imageSource, getSurfaceId()),
|
||||
};
|
||||
setStateData(std::move(state));
|
||||
}
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
void RNSVGImageShadowNode::layout(LayoutContext layoutContext) {
|
||||
updateStateIfNeeded();
|
||||
ConcreteViewShadowNode::layout(layoutContext);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and 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 <jsi/jsi.h>
|
||||
#include <react/renderer/components/rnsvg/EventEmitters.h>
|
||||
#include <react/renderer/components/rnsvg/Props.h>
|
||||
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
||||
#include <react/renderer/imagemanager/ImageManager.h>
|
||||
#include <react/renderer/imagemanager/primitives.h>
|
||||
|
||||
#include "RNSVGImageState.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
JSI_EXPORT extern const char RNSVGImageComponentName[];
|
||||
|
||||
/*
|
||||
* `ShadowNode` for <RNSVGImage> component.
|
||||
*/
|
||||
class JSI_EXPORT RNSVGImageShadowNode final : public ConcreteViewShadowNode<
|
||||
RNSVGImageComponentName,
|
||||
RNSVGImageProps,
|
||||
ViewEventEmitter,
|
||||
RNSVGImageState> {
|
||||
public:
|
||||
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
||||
|
||||
static ShadowNodeTraits BaseTraits() {
|
||||
auto traits = ConcreteViewShadowNode::BaseTraits();
|
||||
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
||||
return traits;
|
||||
}
|
||||
|
||||
/*
|
||||
* Associates a shared `ImageManager` with the node.
|
||||
*/
|
||||
void setImageManager(const SharedImageManager &imageManager);
|
||||
|
||||
static RNSVGImageState initialStateData(
|
||||
ShadowNodeFragment const &fragment,
|
||||
ShadowNodeFamilyFragment const &familyFragment,
|
||||
ComponentDescriptor const &componentDescriptor) {
|
||||
auto imageSource = ImageSource{ImageSource::Type::Invalid};
|
||||
return {imageSource, {imageSource, nullptr}};
|
||||
}
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
void layout(LayoutContext layoutContext) override;
|
||||
|
||||
private:
|
||||
ImageSource getImageSource() const;
|
||||
|
||||
SharedImageManager imageManager_;
|
||||
|
||||
void updateStateIfNeeded();
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "RNSVGImageState.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
ImageSource RNSVGImageState::getImageSource() const {
|
||||
return imageSource_;
|
||||
}
|
||||
|
||||
ImageRequest const &RNSVGImageState::getImageRequest() const {
|
||||
return *imageRequest_;
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
64
common/cpp/react/renderer/components/rnsvg/RNSVGImageState.h
Normal file
64
common/cpp/react/renderer/components/rnsvg/RNSVGImageState.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and 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 <jsi/jsi.h>
|
||||
#include <react/renderer/imagemanager/ImageRequest.h>
|
||||
#include <react/renderer/imagemanager/primitives.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <react/renderer/mapbuffer/MapBuffer.h>
|
||||
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
||||
#endif
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* State for <Image> component.
|
||||
*/
|
||||
class JSI_EXPORT RNSVGImageState final {
|
||||
public:
|
||||
RNSVGImageState(ImageSource const &imageSource, ImageRequest imageRequest)
|
||||
: imageSource_(imageSource),
|
||||
imageRequest_(
|
||||
std::make_shared<ImageRequest>(std::move(imageRequest))){};
|
||||
|
||||
/*
|
||||
* Returns stored ImageSource object.
|
||||
*/
|
||||
ImageSource getImageSource() const;
|
||||
|
||||
/*
|
||||
* Exposes for reading stored `ImageRequest` object.
|
||||
* `ImageRequest` object cannot be copied or moved from `ImageLocalData`.
|
||||
*/
|
||||
ImageRequest const &getImageRequest() const;
|
||||
|
||||
#ifdef ANDROID
|
||||
RNSVGImageState(RNSVGImageState const &previousState, folly::dynamic data){};
|
||||
|
||||
/*
|
||||
* Empty implementation for Android because it doesn't use this class.
|
||||
*/
|
||||
folly::dynamic getDynamic() const {
|
||||
return {};
|
||||
};
|
||||
|
||||
MapBuffer getMapBuffer() const {
|
||||
return MapBufferBuilder::EMPTY();
|
||||
};
|
||||
#endif
|
||||
|
||||
private:
|
||||
ImageSource imageSource_;
|
||||
std::shared_ptr<ImageRequest> imageRequest_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
Reference in New Issue
Block a user