Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸš€ Enhance React Native Layout Management: Native Layout Manager for Padding and Calculations! πŸ’ͺ #48655

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* 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.
*
* @flow strict
* @format
*/

export * from '../../../src/private/specs/modules/NativeLayoutManager';
import LayoutManager from '../../../src/private/specs/modules/NativeLayoutManager';
export default LayoutManager;
55 changes: 55 additions & 0 deletions packages/react-native/ReactCommon/yoga/yoga/YGModule.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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 "YGModule.h"
#include <ReactCommon/CallInvoker.h>
#include <jsi/jsi.h>
#include <Yoga.h>

namespace yoga {

YogaModule::YogaModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker)
: facebook::react::NativeModule("YogaModule", jsInvoker) {}

std::string YogaModule::getName() {
return "YogaModule";
}

void YogaModule::calculateLayout(float width, float height) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);

// Set the layout properties
YGNodeStyleSetWidth(root, width);
YGNodeStyleSetHeight(root, height);

// Perform the layout calculation
YGNodeCalculateLayout(root, width, height, YGDirectionLTR);

// Retrieve the layout results
float x = YGNodeLayoutGetLeft(root);
float y = YGNodeLayoutGetTop(root);

// Output the result (for debugging purposes)
printf("Yoga Layout: X=%f, Y=%f\n", x, y);

// Clean up the Yoga node and config
YGNodeFree(root);
YGConfigFree(config);
}

// Wrapper to expose the calculateLayout function to JavaScript
void YogaModule::calculateLayoutWrapper(
const facebook::react::CallInvoker& jsInvoker,
float width,
float height
) {
YogaModule* module = new YogaModule(jsInvoker);
module->calculateLayout(width, height);
}

} // namespace yoga
33 changes: 33 additions & 0 deletions packages/react-native/ReactCommon/yoga/yoga/YGModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 <ReactCommon/cxxreact/NativeModule.h>
#include <ReactCommon/CallInvoker.h>
#include <jsi/jsi.h>
#include <Yoga.h>

namespace yoga {

class YogaModule : public facebook::react::NativeModule {
public:
YogaModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker);

std::string getName() override;

// Exposed to JavaScript
void calculateLayout(float width, float height);

static void calculateLayoutWrapper(
const facebook::react::CallInvoker& jsInvoker,
float width,
float height
);
};

} // namespace yoga
15 changes: 15 additions & 0 deletions packages/react-native/ReactCommon/yoga/yoga/YGNodeLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ float getResolvedLayoutProperty(const YGNodeConstRef nodeRef, const Edge edge) {
return (node->getLayout().*LayoutMember)(static_cast<PhysicalEdge>(edge));
}

void fixFlexWrapAlignmentIssue(YGNodeRef node) {
if (node->getStyle().flexWrap() != YGWrap::NoWrap &&
node->getStyle().alignItems() == YGAlign::FlexEnd) {
for (size_t i = 0; i < node->getChildCount(); ++i) {
auto child = node->getChild(i);
const float parentHeight = node->getLayout().dimension(Dimension::Height);
const float childHeight = child->getLayout().dimension(Dimension::Height);
const float offset = parentHeight - childHeight;

child->setLayoutPosition(
offset, static_cast<uint8_t>(PhysicalEdge::Top));
}
}
}

} // namespace

float YGNodeLayoutGetLeft(const YGNodeConstRef node) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NativeModules } from 'react-native';

const { NativeLayoutManager } = NativeModules;

class LayoutManager {
// Example method to set padding values for a view
static setPadding(viewId, top, right, bottom, left) {
if (NativeLayoutManager) {
NativeLayoutManager.setPadding(viewId, top, right, bottom, left);
} else {
console.warn('NativeLayoutManager module is not available.');
}
}

// Example method to get the calculated layout (e.g., width, height)
static getLayout(viewId) {
return NativeLayoutManager ? NativeLayoutManager.getLayout(viewId) : null;
}

// Example method to perform layout calculation
static calculateLayout(viewId, width, height) {
if (NativeLayoutManager) {
return NativeLayoutManager.calculateLayout(viewId, width, height);
}
return null;
}
}

export default LayoutManager;
Loading