Skip to content

Commit a993eb7

Browse files
authored
Merge branch 'master' into feat/ios26_searchbar-change
2 parents c060495 + 872e62c commit a993eb7

File tree

9 files changed

+176
-10
lines changed

9 files changed

+176
-10
lines changed

android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsContainer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ class TitleAndButtonsContainer(context: Context) : ViewGroup(context) {
155155
val rightBarWidth = rightButtonBar.measuredWidth
156156
val leftBarWidth = leftButtonBar.measuredWidth
157157
val isCenter = titleComponentAlignment == Alignment.Center
158+
val isFill = titleComponentAlignment == Alignment.Fill
158159
val titleHeightMeasureSpec = MeasureSpec.makeMeasureSpec(containerHeight, MeasureSpec.AT_MOST)
159-
val titleWidthMeasureSpec = makeTitleAtMostWidthMeasureSpec(containerWidth, rightBarWidth, leftBarWidth, isCenter)
160+
val titleWidthMeasureSpec = makeTitleAtMostWidthMeasureSpec(containerWidth, rightBarWidth, leftBarWidth, isCenter, isFill)
160161
if (titleComponent is TitleBarReactView) {
161162
titleComponent.centered = isCenter
162163
}

android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsMeasurer.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ typealias TitleRight = Int
1515
typealias TitleTop = Int
1616
typealias TitleBottom = Int
1717

18-
fun makeTitleAtMostWidthMeasureSpec(containerWidth: Int, rightBarWidth: Int, leftBarWidth: Int, isCenter: Boolean): Int {
18+
fun makeTitleAtMostWidthMeasureSpec(containerWidth: Int, rightBarWidth: Int, leftBarWidth: Int, isCenter: Boolean, isFill: Boolean = false): Int {
1919
return if (isCenter) {
2020
View.MeasureSpec.makeMeasureSpec(containerWidth, View.MeasureSpec.AT_MOST)
2121
} else {
22-
View.MeasureSpec.makeMeasureSpec(containerWidth - rightBarWidth - leftBarWidth - 2 * DEFAULT_LEFT_MARGIN_PX, View.MeasureSpec.AT_MOST)
22+
val availableWidth = containerWidth - rightBarWidth - leftBarWidth - 2 * DEFAULT_LEFT_MARGIN_PX
23+
View.MeasureSpec.makeMeasureSpec(
24+
availableWidth,
25+
if (isFill) View.MeasureSpec.EXACTLY else View.MeasureSpec.AT_MOST
26+
)
2327
}
2428
}
2529

ios/RNNReactTitleView.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
@implementation RNNReactTitleView {
44
BOOL _fillParent;
5+
CGFloat _expectedHeight;
56
}
67

78
- (NSString *)componentType {
@@ -10,7 +11,7 @@ - (NSString *)componentType {
1011

1112
- (CGSize)intrinsicContentSize {
1213
if (_fillParent) {
13-
return UILayoutFittingExpandedSize;
14+
return CGSizeMake(UILayoutFittingExpandedSize.width, _expectedHeight > 0 ? _expectedHeight : 44);
1415
} else {
1516
return [super intrinsicContentSize];
1617
}
@@ -19,6 +20,7 @@ - (CGSize)intrinsicContentSize {
1920
- (void)setAlignment:(NSString *)alignment inFrame:(CGRect)frame {
2021
if ([alignment isEqualToString:@"fill"]) {
2122
_fillParent = YES;
23+
_expectedHeight = frame.size.height;
2224
self.translatesAutoresizingMaskIntoConstraints = NO;
2325
self.sizeFlexibility = RCTRootViewSizeFlexibilityNone;
2426
} else {

playground/e2e/Options.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ describe('Options', () => {
5555
await expect(elementByLabel('Title Changed')).toBeVisible();
5656
});
5757

58+
it('TopBar custom title with subtitle should be visible', async () => {
59+
await elementById(TestIDs.GOTO_TOPBAR_TITLE_TEST).tap();
60+
await expect(elementById(TestIDs.TOPBAR_TITLE_TEXT)).toBeVisible();
61+
await expect(elementById(TestIDs.TOPBAR_TITLE_AVATAR)).toBeVisible();
62+
});
63+
64+
it('TopBar custom title without subtitle should be visible', async () => {
65+
await elementById(TestIDs.GOTO_TOPBAR_TITLE_TEST).tap();
66+
await elementById(TestIDs.SET_TOPBAR_WITHOUT_SUBTITLE_BTN).tap();
67+
await expect(elementById(TestIDs.TOPBAR_TITLE_TEXT)).toBeVisible();
68+
await expect(elementById(TestIDs.TOPBAR_TITLE_AVATAR)).toBeVisible();
69+
});
70+
5871
it('Popping screen with yellow box should not crash', async () => {
5972
await elementById(TestIDs.SHOW_YELLOW_BOX_BTN).tap();
6073
await elementById(TestIDs.PUSH_BTN).tap();

playground/src/screens/OptionsScreen.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ const {
2020
GOTO_SEARCHBAR_MODAL,
2121
REPLACE_TAB_TEST_ID,
2222
REPLACED_TAB,
23+
GOTO_TOPBAR_TITLE_TEST,
2324
} = testIDs;
2425

25-
interface Props extends NavigationProps {}
26+
interface Props extends NavigationProps { }
2627

2728
export default class Options extends NavigationComponent<Props> {
2829
static options() {
@@ -75,6 +76,11 @@ export default class Options extends NavigationComponent<Props> {
7576
testID={SET_REACT_TITLE_VIEW}
7677
onPress={this.setReactTitleView}
7778
/>
79+
<Button
80+
label="TopBar Title Test"
81+
testID={GOTO_TOPBAR_TITLE_TEST}
82+
onPress={this.gotoTopBarTitleTest}
83+
/>
7884
<Button
7985
label="Show Yellow Box"
8086
testID={SHOW_YELLOW_BOX_BTN}
@@ -136,6 +142,13 @@ export default class Options extends NavigationComponent<Props> {
136142
},
137143
});
138144

145+
gotoTopBarTitleTest = () =>
146+
Navigation.push(this, {
147+
component: {
148+
name: Screens.TopBarTitleTest,
149+
},
150+
});
151+
139152
hideSearchBar = () =>
140153
Navigation.mergeOptions(this, {
141154
topBar: {

playground/src/screens/Screens.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ const Screens = {
132132
SearchBar: 'SearchBar',
133133
SearchBarModal: 'SearchBarModal',
134134
TopBar: 'TopBar',
135+
TopBarTitleTest: 'TopBarTitleTest',
135136
};
136137

137138
export default Screens;
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import React from 'react';
2+
import { View, Text } from 'react-native';
3+
import { NavigationComponent, NavigationProps, Navigation as Nav } from 'react-native-navigation';
4+
import Button from '../components/Button';
5+
import Root from '../components/Root';
6+
import Navigation from '../services/Navigation';
7+
import testIDs from '../testIDs';
8+
9+
const {
10+
TOPBAR_TITLE_TEXT,
11+
TOPBAR_TITLE_AVATAR,
12+
SET_TOPBAR_WITH_SUBTITLE_BTN,
13+
SET_TOPBAR_WITHOUT_SUBTITLE_BTN,
14+
} = testIDs;
15+
16+
// TopBar title component WITH subtitle
17+
function TopBarWithSubtitle() {
18+
return (
19+
<View style={{ flex: 1 }}>
20+
<View style={{ flexDirection: 'row' }}>
21+
<View
22+
testID={TOPBAR_TITLE_AVATAR}
23+
style={{ alignSelf: 'center', marginRight: 20, width: 10, height: 10, backgroundColor: 'red' }}
24+
/>
25+
<View style={{ flex: 1, justifyContent: 'center' }}>
26+
<Text testID={TOPBAR_TITLE_TEXT} numberOfLines={1}>
27+
Title - pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas sed
28+
</Text>
29+
<Text numberOfLines={1}>Subtitle</Text>
30+
</View>
31+
</View>
32+
</View>
33+
);
34+
}
35+
36+
// TopBar title component WITHOUT subtitle - this triggers the bug on Android
37+
function TopBarWithoutSubtitle() {
38+
return (
39+
<View style={{ flex: 1 }}>
40+
<View style={{ flexDirection: 'row' }}>
41+
<View
42+
testID={TOPBAR_TITLE_AVATAR}
43+
style={{ alignSelf: 'center', marginRight: 20, width: 10, height: 10, backgroundColor: 'red' }}
44+
/>
45+
<View style={{ flex: 1, justifyContent: 'center' }}>
46+
<Text testID={TOPBAR_TITLE_TEXT} numberOfLines={1}>
47+
Title - pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas sed
48+
</Text>
49+
{/* No subtitle - this causes the bug on Android */}
50+
</View>
51+
</View>
52+
</View>
53+
);
54+
}
55+
56+
Nav.registerComponent('TopBarWithSubtitle', () => TopBarWithSubtitle);
57+
Nav.registerComponent('TopBarWithoutSubtitle', () => TopBarWithoutSubtitle);
58+
59+
interface Props extends NavigationProps { }
60+
61+
export default class TopBarTitleTestScreen extends NavigationComponent<Props> {
62+
static options() {
63+
return {
64+
topBar: {
65+
title: {
66+
component: {
67+
name: 'TopBarWithSubtitle',
68+
alignment: 'fill',
69+
},
70+
},
71+
},
72+
};
73+
}
74+
75+
constructor(props: Props) {
76+
super(props);
77+
Navigation.events().bindComponent(this);
78+
}
79+
80+
render() {
81+
return (
82+
<Root componentId={this.props.componentId}>
83+
<Button
84+
label="With Subtitle"
85+
testID={SET_TOPBAR_WITH_SUBTITLE_BTN}
86+
onPress={this.setTopBarWithSubtitle}
87+
/>
88+
<Button
89+
label="Without Subtitle (Bug Test)"
90+
testID={SET_TOPBAR_WITHOUT_SUBTITLE_BTN}
91+
onPress={this.setTopBarWithoutSubtitle}
92+
/>
93+
</Root>
94+
);
95+
}
96+
97+
setTopBarWithSubtitle = () =>
98+
Navigation.mergeOptions(this, {
99+
topBar: {
100+
title: {
101+
component: {
102+
name: 'TopBarWithSubtitle',
103+
alignment: 'fill',
104+
},
105+
},
106+
},
107+
});
108+
109+
setTopBarWithoutSubtitle = () =>
110+
Navigation.mergeOptions(this, {
111+
topBar: {
112+
title: {
113+
component: {
114+
name: 'TopBarWithoutSubtitle',
115+
alignment: 'fill',
116+
},
117+
},
118+
},
119+
});
120+
}
121+

playground/src/screens/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,21 @@ function registerScreens() {
123123
() => require('../components/TopBarBackground').default
124124
);
125125
Navigation.registerComponent(Screens.Toast, () => require('./Toast').default);
126+
Navigation.registerComponent(
127+
Screens.TopBarTitleTest,
128+
() => require('./TopBarTitleTestScreen').default
129+
);
126130

127131
const { ContextProvider } = require('../context');
128132
const ContextScreen = require('./ContextScreen').default;
129133
Navigation.registerComponent(
130134
Screens.ContextScreen,
131135
() => (props) =>
132-
(
133-
<ContextProvider>
134-
<ContextScreen {...props} />
135-
</ContextProvider>
136-
),
136+
(
137+
<ContextProvider>
138+
<ContextScreen {...props} />
139+
</ContextProvider>
140+
),
137141
() => ContextScreen
138142
);
139143

playground/src/testIDs.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ const testIDs = {
220220
REPLACED_TAB: 'REPLACED_TAB',
221221
TOGGLE_PLACEMENT_BTN: 'TOGGLE_PLACEMENT_BTN',
222222
MOUNTED_SCREENS_TEXT: 'MOUNTED_SCREENS_TEXT',
223+
224+
GOTO_TOPBAR_TITLE_TEST: 'GOTO_TOPBAR_TITLE_TEST',
225+
TOPBAR_TITLE_TEXT: 'TOPBAR_TITLE_TEXT',
226+
TOPBAR_TITLE_AVATAR: 'TOPBAR_TITLE_AVATAR',
227+
SET_TOPBAR_WITH_SUBTITLE_BTN: 'SET_TOPBAR_WITH_SUBTITLE_BTN',
228+
SET_TOPBAR_WITHOUT_SUBTITLE_BTN: 'SET_TOPBAR_WITHOUT_SUBTITLE_BTN',
229+
223230
SCREEN_ROOT: 'SCREEN_ROOT',
224231
SCREEN_ROOT_LIST: 'SCREEN_ROOT_LIST',
225232

0 commit comments

Comments
 (0)