Skip to content

Commit 4a56cf5

Browse files
committed
wip: add screen wrappers and update their shadow node state
1 parent 3e638aa commit 4a56cf5

13 files changed

+167
-96
lines changed

packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewComponentDescriptor.h

Lines changed: 0 additions & 28 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifdef __cplusplus
2+
3+
#pragma once
4+
5+
#include <react/renderer/components/RNCTabView/RNCTabViewScreenShadowNode.h>
6+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
7+
8+
namespace facebook::react {
9+
10+
class RNCTabViewScreenComponentDescriptor final : public ConcreteComponentDescriptor<RNCTabViewScreenShadowNode>
11+
{
12+
public:
13+
RNCTabViewScreenComponentDescriptor(const ComponentDescriptorParameters &parameters)
14+
: ConcreteComponentDescriptor(parameters) {}
15+
16+
17+
/**
18+
Retrieve shadow node's state and update it's layout size accordingly.
19+
This is needed because we need to accomodate for bottom bar / sidebar size.
20+
*/
21+
void adopt(ShadowNode &shadowNode) const override {
22+
auto& layoutableShadowNode = static_cast<RNCTabViewScreenShadowNode&>(shadowNode);
23+
auto& stateData = layoutableShadowNode.getStateData();
24+
25+
layoutableShadowNode.setSize(stateData.frameSize);
26+
27+
ConcreteComponentDescriptor::adopt(shadowNode);
28+
}
29+
};
30+
31+
}
32+
33+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "RNCTabViewScreenShadowNode.h"
2+
3+
namespace facebook::react {
4+
5+
extern const char RNCTabViewScreenComponentName[] = "RNCTabViewScreen";
6+
7+
}

packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewShadowNode.h renamed to packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewScreenShadowNode.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#pragma once
44

55
#include <jsi/jsi.h>
6-
#include <react/renderer/components/RNCTabView/RNCTabViewState.h>
6+
#include <react/renderer/components/RNCTabView/RNCTabViewScreenState.h>
77
#include <react/renderer/components/RNCTabView/Props.h>
88
#include <react/renderer/components/RNCTabView/EventEmitters.h>
99
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
@@ -12,26 +12,20 @@
1212

1313
namespace facebook::react {
1414

15-
JSI_EXPORT extern const char RNCTabViewComponentName[];
15+
JSI_EXPORT extern const char RNCTabViewScreenComponentName[];
1616

1717
/*
18-
* `ShadowNode` for <RNCTabView> component.
18+
* `ShadowNode` for <RNCTabViewScreen> component.
1919
*/
20-
class JSI_EXPORT RNCTabViewShadowNode final
20+
class JSI_EXPORT RNCTabViewScreenShadowNode final
2121
: public ConcreteViewShadowNode<
22-
RNCTabViewComponentName,
23-
RNCTabViewProps,
24-
RNCTabViewEventEmitter,
25-
RNCTabViewState>
22+
RNCTabViewScreenComponentName,
23+
RNCTabViewScreenProps,
24+
RNCTabViewScreenEventEmitter,
25+
RNCTabViewScreenState>
2626
{
2727
public:
2828
using ConcreteViewShadowNode::ConcreteViewShadowNode;
29-
30-
void updateStateIfNeeded();
31-
32-
#pragma mark - ShadowNode overrides
33-
34-
void layout(LayoutContext layoutContext) override;
3529
};
3630
}
3731

packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewState.h renamed to packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewScreenState.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010

1111
namespace facebook::react {
1212

13-
class RNCTabViewState
13+
class RNCTabViewScreenState
1414
{
1515
public:
16-
RNCTabViewState() = default;
17-
RNCTabViewState(Size frameSize): frameSize(frameSize) {};
18-
16+
RNCTabViewScreenState() = default;
17+
RNCTabViewScreenState(Size frameSize): frameSize(frameSize) {};
18+
1919
Size frameSize;
2020
};
2121

packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewShadowNode.cpp

Lines changed: 0 additions & 37 deletions
This file was deleted.

packages/react-native-bottom-tabs/ios/Fabric/RCTTabViewComponentView.mm

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifdef RCT_NEW_ARCH_ENABLED
22
#import "RCTTabViewComponentView.h"
3+
#import "RCTTabViewScreenComponentView.h"
34

45
#import <react/renderer/components/RNCTabView/ComponentDescriptors.h>
5-
#import <react/renderer/components/RNCTabView/RNCTabViewComponentDescriptor.h>
66
#import <react/renderer/components/RNCTabView/EventEmitters.h>
77
#import <react/renderer/components/RNCTabView/Props.h>
88
#import <react/renderer/components/RNCTabView/RCTComponentViewHelpers.h>
@@ -38,7 +38,6 @@ @interface RCTTabViewComponentView () <RCTRNCTabViewViewProtocol, TabViewProvide
3838
@implementation RCTTabViewComponentView {
3939
TabViewProvider *_tabViewProvider;
4040
NSMutableArray<PlatformView *> *_reactSubviews;
41-
RNCTabViewShadowNode::ConcreteState::Shared _state;
4241
}
4342

4443
+ (ComponentDescriptorProvider)componentDescriptorProvider
@@ -86,10 +85,6 @@ - (void)unmountChildComponentView:(PlatformView<RCTComponentViewProtocol> *)chil
8685
[childComponentView removeFromSuperview];
8786
}
8887

89-
- (void)updateState:(const facebook::react::State::Shared &)state oldState:(const facebook::react::State::Shared &)oldState {
90-
_state = std::static_pointer_cast<const RNCTabViewShadowNode::ConcreteState>(state);
91-
}
92-
9388
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
9489
{
9590
const auto &oldViewProps = *std::static_pointer_cast<RNCTabViewProps const>(_props);
@@ -250,8 +245,25 @@ - (void)onTabBarMeasuredWithHeight:(NSInteger)height reactTag:(NSNumber *)reactT
250245
}
251246
}
252247

248+
- (size_t)getSelectedIndex
249+
{
250+
const auto &props = *std::static_pointer_cast<RNCTabViewProps const>(_props);
251+
252+
auto selectedItem = std::find_if(props.items.begin(), props.items.end(),
253+
[&](const RNCTabViewItemsStruct &item) {
254+
return item.key == props.selectedPage;
255+
});
256+
257+
return std::distance(props.items.begin(), selectedItem);
258+
}
259+
253260
- (void)onLayoutWithSize:(CGSize)size reactTag:(NSNumber *)reactTag {
254-
_state->updateState(RNCTabViewState({size.width, size.height}));
261+
size_t selectedIndex = [self getSelectedIndex];
262+
263+
RCTTabViewScreenComponentView *child = (RCTTabViewScreenComponentView *)_reactSubviews[selectedIndex];
264+
if ([child respondsToSelector:@selector(updateFrameSize:)]) {
265+
[child updateFrameSize:size];
266+
}
255267
}
256268

257269
@end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifdef RCT_NEW_ARCH_ENABLED
2+
#import <React/RCTViewComponentView.h>
3+
#if TARGET_OS_OSX
4+
#import <AppKit/AppKit.h>
5+
#else
6+
#import <UIKit/UIKit.h>
7+
#endif
8+
9+
NS_ASSUME_NONNULL_BEGIN
10+
11+
@interface RCTTabViewScreenComponentView: RCTViewComponentView
12+
13+
- (void)updateFrameSize:(CGSize)size;
14+
15+
@end
16+
17+
NS_ASSUME_NONNULL_END
18+
19+
#endif /* RCT_NEW_ARCH_ENABLED */
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#ifdef RCT_NEW_ARCH_ENABLED
2+
#import "RCTTabViewScreenComponentView.h"
3+
4+
#import <react/renderer/components/RNCTabView/RNCTabViewScreenComponentDescriptor.h>
5+
#import <react/renderer/components/RNCTabView/EventEmitters.h>
6+
#import <react/renderer/components/RNCTabView/Props.h>
7+
#import <react/renderer/components/RNCTabView/RCTComponentViewHelpers.h>
8+
9+
#import <React/RCTFabricComponentsPlugins.h>
10+
11+
#if TARGET_OS_OSX
12+
typedef NSView PlatformView;
13+
#else
14+
typedef UIView PlatformView;
15+
#endif
16+
17+
18+
using namespace facebook::react;
19+
20+
@interface RCTTabViewScreenComponentView () <RCTRNCTabViewScreenViewProtocol> {
21+
}
22+
23+
@end
24+
25+
@implementation RCTTabViewScreenComponentView {
26+
RNCTabViewScreenShadowNode::ConcreteState::Shared _state;
27+
}
28+
29+
+ (ComponentDescriptorProvider)componentDescriptorProvider
30+
{
31+
return concreteComponentDescriptorProvider<RNCTabViewScreenComponentDescriptor>();
32+
}
33+
34+
- (instancetype)initWithFrame:(CGRect)frame
35+
{
36+
if (self = [super initWithFrame:frame]) {
37+
static const auto defaultProps = std::make_shared<const RNCTabViewScreenProps>();
38+
_props = defaultProps;
39+
}
40+
41+
return self;
42+
}
43+
44+
- (void)updateState:(const facebook::react::State::Shared &)state oldState:(const facebook::react::State::Shared &)oldState {
45+
_state = std::static_pointer_cast<const RNCTabViewScreenShadowNode::ConcreteState>(state);
46+
}
47+
48+
- (void)updateFrameSize:(CGSize)size
49+
{
50+
_state->updateState(RNCTabViewScreenState({size.width, size.height}));
51+
}
52+
53+
@end
54+
55+
Class<RCTComponentViewProtocol> RNCTabViewScreenCls(void)
56+
{
57+
return RCTTabViewScreenComponentView.class;
58+
}
59+
60+
#endif // RCT_NEW_ARCH_ENABLED
61+
62+
63+

packages/react-native-bottom-tabs/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@
127127
},
128128
"ios": {
129129
"componentProvider": {
130-
"RNCTabView": "RCTTabViewComponentView"
130+
"RNCTabView": "RCTTabViewComponentView",
131+
"RNCTabViewScreen": "RCTTabViewScreenComponentView"
131132
}
132133
}
133134
}

packages/react-native-bottom-tabs/src/TabView.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import NativeTabView from './TabViewNativeComponent';
1616
import useLatestCallback from 'use-latest-callback';
1717
import type { BaseRoute, NavigationState } from './types';
1818
import DelayedFreeze from './DelayedFreeze';
19+
import TabViewScreenNativeComponent from './TabViewScreenNativeComponent';
1920

2021
const isAppleSymbol = (icon: any): icon is { sfSymbol: string } =>
2122
icon?.sfSymbol;
@@ -324,7 +325,7 @@ const TabView = <Route extends BaseRoute>({
324325
const freeze = !focused ? getFreezeOnBlur({ route }) : false;
325326

326327
return (
327-
<View
328+
<TabViewScreenNativeComponent
328329
key={route.key}
329330
collapsable={false}
330331
style={[styles.screen, styles.fullWidth]}
@@ -340,7 +341,7 @@ const TabView = <Route extends BaseRoute>({
340341
jumpTo,
341342
})}
342343
</DelayedFreeze>
343-
</View>
344+
</TabViewScreenNativeComponent>
344345
);
345346
})}
346347
</NativeTabView>

packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,4 @@ export interface TabViewProps extends ViewProps {
5858
fontSize?: Int32;
5959
}
6060

61-
export default codegenNativeComponent<TabViewProps>('RNCTabView', {
62-
interfaceOnly: true,
63-
});
61+
export default codegenNativeComponent<TabViewProps>('RNCTabView');
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { ViewProps } from 'react-native';
2+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
3+
4+
export interface TabViewScreenProps extends ViewProps {}
5+
6+
export default codegenNativeComponent<TabViewScreenProps>('RNCTabViewScreen', {
7+
interfaceOnly: true,
8+
});

0 commit comments

Comments
 (0)