@momo-kits/foundation 0.167.1-duo.12 → 0.167.1-duo.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Application/BottomTab/index.tsx +2 -7
- package/Application/Components/HeaderExtendHeader.tsx +15 -5
- package/Application/Components/HeaderLeft.tsx +16 -1
- package/Application/Components/HeaderRight.tsx +39 -1
- package/Application/Components/HeaderTitle.tsx +17 -3
- package/Application/Components/SearchHeader.tsx +7 -1
- package/Application/Components/SideBarButton.tsx +15 -4
- package/Application/NavigationContainer.tsx +3 -5
- package/Layout/Screen.tsx +4 -0
- package/Layout/utils.ts +91 -1
- package/package.json +1 -1
|
@@ -31,6 +31,7 @@ import { DuoTabBar } from './DuoTabBar';
|
|
|
31
31
|
import { DuoBarCompressionProvider } from './DuoBarCompression';
|
|
32
32
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
33
33
|
import { useScreenLayout } from '../../Layout';
|
|
34
|
+
import { getHeaderRowOptions } from '../../Layout/utils';
|
|
34
35
|
|
|
35
36
|
const Tab = createBottomTabNavigator();
|
|
36
37
|
const Stack = createStackNavigator();
|
|
@@ -39,13 +40,7 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
39
40
|
const { navigator } = useContext(ApplicationContext);
|
|
40
41
|
const context = useContext<any>(MiniAppContext);
|
|
41
42
|
const { nested, options, screen, initialParams } = route?.params;
|
|
42
|
-
const
|
|
43
|
-
const headerStyleOptions = {
|
|
44
|
-
headerStyle: {
|
|
45
|
-
height: headerHeight,
|
|
46
|
-
},
|
|
47
|
-
headerStatusBarHeight,
|
|
48
|
-
};
|
|
43
|
+
const headerStyleOptions = getHeaderRowOptions(useScreenLayout());
|
|
49
44
|
|
|
50
45
|
const opacityValue = 0.3;
|
|
51
46
|
const scaleValue = 0.97;
|
|
@@ -16,7 +16,7 @@ import { SearchHeaderProps } from '../types';
|
|
|
16
16
|
import BackgroundImageView from './BackgroundImageView';
|
|
17
17
|
import { AnimatedCompatValue, useNormalizedSharedValue } from '../utils';
|
|
18
18
|
import { useScreenLayout } from '../../Layout';
|
|
19
|
-
import { HeaderMetrics } from '../../Layout/utils';
|
|
19
|
+
import { DuoMetrics, HeaderMetrics } from '../../Layout/utils';
|
|
20
20
|
|
|
21
21
|
const SCREEN_PADDING = 12;
|
|
22
22
|
const BACK_WIDTH = 28;
|
|
@@ -51,17 +51,27 @@ const HeaderExtendHeader: React.FC<{
|
|
|
51
51
|
const headerBackground = customBackground ?? theme.assets?.headerBackground;
|
|
52
52
|
const layout = useScreenLayout();
|
|
53
53
|
|
|
54
|
+
// the iPhone Duo status bar row keeps side bar sized back and toolkit
|
|
55
|
+
const backWidth = layout.statusBarClearance
|
|
56
|
+
? DuoMetrics.controlSize
|
|
57
|
+
: BACK_WIDTH;
|
|
58
|
+
const toolkitWidth = layout.statusBarClearance
|
|
59
|
+
? DuoMetrics.itemPitch * 2 + SCREEN_PADDING
|
|
60
|
+
: TOOLKIT_WIDTH;
|
|
54
61
|
const leftPosition =
|
|
55
62
|
inputSearchProps?.leftPosition ||
|
|
56
|
-
(layout.sideBar ? SCREEN_PADDING :
|
|
63
|
+
(layout.sideBar ? SCREEN_PADDING : backWidth + 20);
|
|
57
64
|
const headerRightWidth =
|
|
58
|
-
customHeaderRightWidth ?? (layout.sideBar ? 0 :
|
|
65
|
+
customHeaderRightWidth ?? (layout.sideBar ? 0 : toolkitWidth);
|
|
59
66
|
const contentLeft = layout.insetLeft + SCREEN_PADDING;
|
|
60
67
|
const contentRight = layout.insetLeft + layout.contentWidth;
|
|
61
|
-
|
|
68
|
+
// collapsed on the status bar row, the search stays between its clusters
|
|
69
|
+
const collapsedLeft =
|
|
70
|
+
layout.insetLeft + leftPosition + (layout.statusBarClearance?.left ?? 0);
|
|
71
|
+
const collapsedRight = contentRight - (layout.statusBarClearance?.right ?? 0);
|
|
62
72
|
const searchWidth = layout.contentWidth - SCREEN_PADDING * 2;
|
|
63
73
|
const collapsedSearchWidth =
|
|
64
|
-
|
|
74
|
+
collapsedRight - collapsedLeft - SCREEN_PADDING - headerRightWidth;
|
|
65
75
|
// a row taller than barHeight (iPhone Duo) centers the collapsed search on the title
|
|
66
76
|
const collapsedRaise =
|
|
67
77
|
(layout.headerHeight -
|
|
@@ -6,7 +6,7 @@ import { PopupNotify } from '../../Popup';
|
|
|
6
6
|
import { NavigationButton } from './NavigationButton';
|
|
7
7
|
import { SideBarButton } from './SideBarButton';
|
|
8
8
|
import Animated from 'react-native-reanimated';
|
|
9
|
-
import { useSideBarItemStyle } from '../../Layout/utils';
|
|
9
|
+
import { useScreenLayout, useSideBarItemStyle } from '../../Layout/utils';
|
|
10
10
|
import { useSideBarCounterStyle } from './DuoQuickReturnHeader';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -23,6 +23,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
23
23
|
const { navigator } = useContext(ApplicationContext);
|
|
24
24
|
const sideBarStyle = useSideBarItemStyle('left', 0);
|
|
25
25
|
const counterStyle = useSideBarCounterStyle();
|
|
26
|
+
const { statusBarClearance } = useScreenLayout();
|
|
26
27
|
|
|
27
28
|
const goBack = useCallback(() => {
|
|
28
29
|
const canGoBack = navigator?.ref?.current?.canGoBack?.();
|
|
@@ -95,6 +96,20 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
95
96
|
);
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
// on the status bar row the controls keep the side bar size
|
|
100
|
+
if (statusBarClearance) {
|
|
101
|
+
return (
|
|
102
|
+
<View style={styles.headerLeft}>
|
|
103
|
+
<SideBarButton
|
|
104
|
+
accessibilityLabel="btn_navigation_back"
|
|
105
|
+
icon="arrow-back"
|
|
106
|
+
tintColor={tintColor}
|
|
107
|
+
onPress={goBackSafe}
|
|
108
|
+
/>
|
|
109
|
+
</View>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
98
113
|
return (
|
|
99
114
|
<View style={styles.headerLeft}>
|
|
100
115
|
<NavigationButton
|
|
@@ -14,7 +14,7 @@ import { Tool, ToolGroup } from '../types';
|
|
|
14
14
|
import { Icon } from '../../Icon';
|
|
15
15
|
import { Text } from '../../Text';
|
|
16
16
|
import Animated from 'react-native-reanimated';
|
|
17
|
-
import { useSideBarItemStyle } from '../../Layout/utils';
|
|
17
|
+
import { useScreenLayout, useSideBarItemStyle } from '../../Layout/utils';
|
|
18
18
|
import { useSideBarCounterStyle } from './DuoQuickReturnHeader';
|
|
19
19
|
import { SideBarButton, SideBarGroup, SideBarGroupItem } from './SideBarButton';
|
|
20
20
|
import { useDuoBarCompression } from '../BottomTab/DuoBarCompression';
|
|
@@ -85,6 +85,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
85
85
|
const context = useContext<any>(MiniAppContext);
|
|
86
86
|
const { toolbarCompressed, toolbarHidden, expandToolbar, setToolbarHeight } =
|
|
87
87
|
useDuoBarCompression();
|
|
88
|
+
const { statusBarClearance } = useScreenLayout();
|
|
88
89
|
|
|
89
90
|
const [isFavorite, setIsFavorite] = useState<boolean>(false);
|
|
90
91
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -358,6 +359,39 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
358
359
|
);
|
|
359
360
|
}
|
|
360
361
|
|
|
362
|
+
// on the status bar row the controls keep the side bar size
|
|
363
|
+
if (statusBarClearance) {
|
|
364
|
+
return (
|
|
365
|
+
<View style={styles.sideBarRow}>
|
|
366
|
+
{useShortcut && (
|
|
367
|
+
<SideBarButton
|
|
368
|
+
disabled={isLoading}
|
|
369
|
+
icon={iconShortcut}
|
|
370
|
+
onPress={shortcutOnPress}
|
|
371
|
+
tintColor={tintColor}
|
|
372
|
+
showBadge={showBadge}
|
|
373
|
+
/>
|
|
374
|
+
)}
|
|
375
|
+
<SideBarGroup tintColor={tintColor} horizontal>
|
|
376
|
+
{useHelpCenter && (
|
|
377
|
+
<SideBarGroupItem
|
|
378
|
+
accessibilityLabel={'btn_navigation_help_center'}
|
|
379
|
+
icon={'help_center'}
|
|
380
|
+
tintColor={tintColor}
|
|
381
|
+
onPress={onPressHelpCenter}
|
|
382
|
+
/>
|
|
383
|
+
)}
|
|
384
|
+
<SideBarGroupItem
|
|
385
|
+
accessibilityLabel={'btn_navigation_close'}
|
|
386
|
+
icon={closeIcon}
|
|
387
|
+
tintColor={tintColor}
|
|
388
|
+
onPress={onClose}
|
|
389
|
+
/>
|
|
390
|
+
</SideBarGroup>
|
|
391
|
+
</View>
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
|
|
361
395
|
return (
|
|
362
396
|
<View style={Styles.row}>
|
|
363
397
|
{useShortcut && (
|
|
@@ -471,6 +505,10 @@ const styles = StyleSheet.create({
|
|
|
471
505
|
sideBarColumn: {
|
|
472
506
|
gap: Spacing.M,
|
|
473
507
|
},
|
|
508
|
+
sideBarRow: {
|
|
509
|
+
flexDirection: 'row',
|
|
510
|
+
gap: Spacing.M,
|
|
511
|
+
},
|
|
474
512
|
headerLeft: {
|
|
475
513
|
marginLeft: 12,
|
|
476
514
|
},
|
|
@@ -33,15 +33,29 @@ const useHeaderFontFamily = (): string => {
|
|
|
33
33
|
*/
|
|
34
34
|
const HEADER_ACTIONS_WIDTH = 172;
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* extra width the 48pt back and toolkit take on the iPhone Duo status bar row
|
|
38
|
+
*/
|
|
39
|
+
const STATUS_BAR_ROW_ACTIONS_EXTRA = 55;
|
|
40
|
+
|
|
36
41
|
/**
|
|
37
42
|
* max title width, the iPhone Duo side bar takes back and toolkit out of the bar
|
|
38
43
|
*/
|
|
39
44
|
const useTitleMaxWidth = () => {
|
|
40
|
-
const { width, contentWidth, sideBar } =
|
|
45
|
+
const { width, contentWidth, sideBar, statusBarClearance } =
|
|
46
|
+
useScreenLayout();
|
|
47
|
+
const clearance = statusBarClearance
|
|
48
|
+
? statusBarClearance.left + statusBarClearance.right
|
|
49
|
+
: 0;
|
|
41
50
|
if (sideBar) {
|
|
42
|
-
return contentWidth - Spacing.M * 2;
|
|
51
|
+
return contentWidth - Spacing.M * 2 - clearance;
|
|
43
52
|
}
|
|
44
|
-
return
|
|
53
|
+
return (
|
|
54
|
+
width -
|
|
55
|
+
HEADER_ACTIONS_WIDTH -
|
|
56
|
+
(statusBarClearance ? STATUS_BAR_ROW_ACTIONS_EXTRA : 0) -
|
|
57
|
+
clearance
|
|
58
|
+
);
|
|
45
59
|
};
|
|
46
60
|
|
|
47
61
|
type HeaderTitleInterpolate = {
|
|
@@ -8,6 +8,7 @@ import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
|
8
8
|
import { Text } from '../../Text';
|
|
9
9
|
import { useNormalizedSharedValue } from '../utils';
|
|
10
10
|
import { useScreenLayout } from '../../Layout';
|
|
11
|
+
import { DuoMetrics } from '../../Layout/utils';
|
|
11
12
|
|
|
12
13
|
const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
13
14
|
(
|
|
@@ -22,8 +23,9 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
22
23
|
) => {
|
|
23
24
|
const { theme, navigator } = useContext(ApplicationContext);
|
|
24
25
|
const context = useContext<any>(MiniAppContext);
|
|
25
|
-
const BACK_WIDTH = 28;
|
|
26
26
|
const layout = useScreenLayout();
|
|
27
|
+
// the iPhone Duo status bar row keeps a side bar sized back button
|
|
28
|
+
const BACK_WIDTH = layout.statusBarClearance ? DuoMetrics.controlSize : 28;
|
|
27
29
|
|
|
28
30
|
const sharedValue = useNormalizedSharedValue(animatedValue);
|
|
29
31
|
const leftPosition = props?.leftPosition ?? BACK_WIDTH + 20;
|
|
@@ -34,6 +36,10 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
34
36
|
if (layout.sideBar) {
|
|
35
37
|
searchMaxWidth = layout.contentWidth - Spacing.M * 2 - headerRightWidth;
|
|
36
38
|
}
|
|
39
|
+
if (layout.statusBarClearance) {
|
|
40
|
+
searchMaxWidth -=
|
|
41
|
+
layout.statusBarClearance.left + layout.statusBarClearance.right;
|
|
42
|
+
}
|
|
37
43
|
|
|
38
44
|
const backgroundStyle = useAnimatedStyle(() => {
|
|
39
45
|
const t = Math.min(Math.max(sharedValue.value / 100, 0), 1);
|
|
@@ -54,19 +54,30 @@ const SideBarButton: React.FC<NavigationButtonProps> = ({
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* 48pt
|
|
57
|
+
* 48pt glass capsule grouping related controls, one item per 50pt, laid out vertically
|
|
58
|
+
* in the side bar or horizontally on a header row
|
|
58
59
|
*/
|
|
59
60
|
const SideBarGroup: React.FC<{
|
|
60
61
|
tintColor?: string;
|
|
62
|
+
horizontal?: boolean;
|
|
61
63
|
style?: StyleProp<ViewStyle>;
|
|
62
64
|
children: ReactNode;
|
|
63
|
-
}> = ({ tintColor, style, children }) => {
|
|
65
|
+
}> = ({ tintColor, horizontal = false, style, children }) => {
|
|
64
66
|
const count = React.Children.toArray(children).length;
|
|
65
|
-
const
|
|
67
|
+
const length =
|
|
66
68
|
count > 1 ? count * DuoMetrics.itemPitch : DuoMetrics.controlSize;
|
|
67
69
|
|
|
68
70
|
return (
|
|
69
|
-
<View
|
|
71
|
+
<View
|
|
72
|
+
style={[
|
|
73
|
+
styles.control,
|
|
74
|
+
getGlassStyle(tintColor),
|
|
75
|
+
horizontal
|
|
76
|
+
? { width: length, flexDirection: 'row' }
|
|
77
|
+
: { height: length },
|
|
78
|
+
style,
|
|
79
|
+
]}
|
|
80
|
+
>
|
|
70
81
|
{children}
|
|
71
82
|
</View>
|
|
72
83
|
);
|
|
@@ -31,6 +31,7 @@ import { HeaderTitle } from './Components/HeaderTitle';
|
|
|
31
31
|
import { HeaderBackground } from './Components/HeaderBackground';
|
|
32
32
|
import { type EdgeInsets } from 'react-native-safe-area-context';
|
|
33
33
|
import { useScreenLayout } from '../Layout';
|
|
34
|
+
import { getHeaderRowOptions } from '../Layout/utils';
|
|
34
35
|
import { ReservedRegionsProvider } from '../Layout/ReservedRegions';
|
|
35
36
|
|
|
36
37
|
const Stack = createStackNavigator();
|
|
@@ -107,7 +108,7 @@ const Navigation: React.FC<any> = ({
|
|
|
107
108
|
const navigationRef = useRef<any>(null);
|
|
108
109
|
const isReady = useRef(false);
|
|
109
110
|
const navigator = useRef(new Navigator(navigationRef, isReady));
|
|
110
|
-
const
|
|
111
|
+
const headerRowOptions = getHeaderRowOptions(useScreenLayout());
|
|
111
112
|
const syncCanGoBack = useNativeCanGoBack();
|
|
112
113
|
const isWhiteList = isWhiteListDesignSystem(context);
|
|
113
114
|
const fontFamily = isWhiteList ? 'MomoTrustSans' : 'SFProText';
|
|
@@ -204,10 +205,7 @@ const Navigation: React.FC<any> = ({
|
|
|
204
205
|
gestureEnabled: false,
|
|
205
206
|
headerTitleAlign: 'center',
|
|
206
207
|
headerTintColor: theme.colors.text.default,
|
|
207
|
-
|
|
208
|
-
height: headerHeight,
|
|
209
|
-
},
|
|
210
|
-
headerStatusBarHeight,
|
|
208
|
+
...headerRowOptions,
|
|
211
209
|
}}
|
|
212
210
|
>
|
|
213
211
|
<Stack.Screen
|
package/Layout/Screen.tsx
CHANGED
|
@@ -525,6 +525,10 @@ const Screen = forwardRef(
|
|
|
525
525
|
searchWidth = layout.contentWidth - Spacing.M * 2;
|
|
526
526
|
searchLeft = Spacing.M - getHeaderMargin(layout.width);
|
|
527
527
|
}
|
|
528
|
+
if (layout.statusBarClearance) {
|
|
529
|
+
searchWidth -=
|
|
530
|
+
layout.statusBarClearance.left + layout.statusBarClearance.right;
|
|
531
|
+
}
|
|
528
532
|
const options: StackNavigationOptions = {
|
|
529
533
|
headerRight: undefined,
|
|
530
534
|
headerTitleContainerStyle: {
|
package/Layout/utils.ts
CHANGED
|
@@ -77,6 +77,9 @@ const HeaderMetrics = {
|
|
|
77
77
|
* - edgeInset: on the outer display in landscape the strip holds no status bar, so its
|
|
78
78
|
* controls start this far from the top and stay this far above the bottom, unless a
|
|
79
79
|
* reserved region (the camera at either end) asks for more
|
|
80
|
+
* - innerStatusBarCenterY / innerStatusBarWidth: on the inner display in portrait the
|
|
81
|
+
* clock and connectivity cluster sits at the top right corner (x 550–643 of 669, clock
|
|
82
|
+
* digits centered on y 47); its reserved region, when reported, is taller than the glyphs
|
|
80
83
|
*/
|
|
81
84
|
const DuoMetrics = {
|
|
82
85
|
maxAspectRatio: 1.6,
|
|
@@ -88,6 +91,8 @@ const DuoMetrics = {
|
|
|
88
91
|
outerHeaderHeight: 76,
|
|
89
92
|
outerCameraCenterY: 45,
|
|
90
93
|
edgeInset: 24,
|
|
94
|
+
innerStatusBarCenterY: 47,
|
|
95
|
+
innerStatusBarWidth: 120,
|
|
91
96
|
};
|
|
92
97
|
|
|
93
98
|
const NO_INSETS: EdgeInsets = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
@@ -124,6 +129,39 @@ const getStripOcclusion = (
|
|
|
124
129
|
{ top: 0, topCenter: 0, bottom: 0 },
|
|
125
130
|
);
|
|
126
131
|
|
|
132
|
+
/**
|
|
133
|
+
* how far the clock and battery clusters of a status bar on the top edge reach in from
|
|
134
|
+
* each side. `undefined` without reserved regions there
|
|
135
|
+
*/
|
|
136
|
+
const getStatusBarClusters = (
|
|
137
|
+
regions: ReservedRegion[],
|
|
138
|
+
windowWidth: number,
|
|
139
|
+
topInset: number,
|
|
140
|
+
) => {
|
|
141
|
+
const midX = windowWidth / 2;
|
|
142
|
+
const clusters = regions.filter(
|
|
143
|
+
region =>
|
|
144
|
+
region.y < topInset &&
|
|
145
|
+
region.y + region.height <= topInset &&
|
|
146
|
+
(region.x + region.width <= midX || region.x >= midX),
|
|
147
|
+
);
|
|
148
|
+
if (!clusters.length) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return clusters.reduce(
|
|
153
|
+
(result, region) => {
|
|
154
|
+
if (region.x < midX) {
|
|
155
|
+
result.left = Math.max(result.left, region.x + region.width);
|
|
156
|
+
} else {
|
|
157
|
+
result.right = Math.max(result.right, windowWidth - region.x);
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
},
|
|
161
|
+
{ left: 0, right: 0 },
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
|
|
127
165
|
const isIPhone = () =>
|
|
128
166
|
Platform.OS === 'ios' && Platform.constants.interfaceIdiom === 'phone';
|
|
129
167
|
|
|
@@ -232,6 +270,17 @@ export type ScreenLayout = {
|
|
|
232
270
|
* bars to the side. `undefined` while the bars stay horizontal.
|
|
233
271
|
*/
|
|
234
272
|
sideBar?: SideBarLayout;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Room the header row keeps from each side for the clock and battery clusters, when
|
|
276
|
+
* iPhone Duo puts the row on the status bar (inner display in portrait).
|
|
277
|
+
*/
|
|
278
|
+
statusBarClearance?: StatusBarClearance;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export type StatusBarClearance = {
|
|
282
|
+
left: number;
|
|
283
|
+
right: number;
|
|
235
284
|
};
|
|
236
285
|
|
|
237
286
|
/**
|
|
@@ -280,6 +329,23 @@ const useScreenLayout = (): ScreenLayout => {
|
|
|
280
329
|
};
|
|
281
330
|
}
|
|
282
331
|
|
|
332
|
+
let statusBarClearance: StatusBarClearance | undefined;
|
|
333
|
+
const isInnerPortrait = height > width && width >= DuoMetrics.innerMinHeight;
|
|
334
|
+
if (isInnerPortrait && insets.top >= HeaderMetrics.statusBarMinInset) {
|
|
335
|
+
// the row shares the status bar band, between its clusters
|
|
336
|
+
const clusters = getStatusBarClusters(
|
|
337
|
+
reservedRegions,
|
|
338
|
+
width,
|
|
339
|
+
insets.top,
|
|
340
|
+
) ?? { left: 0, right: DuoMetrics.innerStatusBarWidth + Spacing.S };
|
|
341
|
+
// center on the clock digits, the region center sits above them
|
|
342
|
+
headerLayout = {
|
|
343
|
+
headerHeight: DuoMetrics.innerStatusBarCenterY * 2,
|
|
344
|
+
headerStatusBarHeight: 0,
|
|
345
|
+
};
|
|
346
|
+
statusBarClearance = clusters;
|
|
347
|
+
}
|
|
348
|
+
|
|
283
349
|
const sideInset = Math.max(insets.left, insets.right);
|
|
284
350
|
let sideBar: SideBarLayout | undefined;
|
|
285
351
|
// narrower strips cannot host a control 12pt from the inner edge
|
|
@@ -295,7 +361,9 @@ const useScreenLayout = (): ScreenLayout => {
|
|
|
295
361
|
height,
|
|
296
362
|
);
|
|
297
363
|
|
|
298
|
-
let top =
|
|
364
|
+
let top = statusBarClearance
|
|
365
|
+
? headerLayout.headerHeight + Spacing.M
|
|
366
|
+
: insets.top + HeaderMetrics.barHeight + Spacing.M;
|
|
299
367
|
if (insets.top < HeaderMetrics.statusBarMinInset) {
|
|
300
368
|
// status bar lives in the strip: start under its cluster, as the native bar does
|
|
301
369
|
const isLandscape = width > height;
|
|
@@ -342,9 +410,30 @@ const useScreenLayout = (): ScreenLayout => {
|
|
|
342
410
|
contentWidth: width - insets.left - insets.right,
|
|
343
411
|
...headerLayout,
|
|
344
412
|
sideBar,
|
|
413
|
+
statusBarClearance,
|
|
345
414
|
};
|
|
346
415
|
};
|
|
347
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Header row options for react-navigation: its height, the room for the status bar, and
|
|
419
|
+
* on iPhone Duo inner portrait the buttons kept clear of the clock and battery clusters
|
|
420
|
+
*/
|
|
421
|
+
const getHeaderRowOptions = ({
|
|
422
|
+
headerHeight,
|
|
423
|
+
headerStatusBarHeight,
|
|
424
|
+
statusBarClearance,
|
|
425
|
+
sideBar,
|
|
426
|
+
}: ScreenLayout) => ({
|
|
427
|
+
headerStyle: { height: headerHeight },
|
|
428
|
+
headerStatusBarHeight,
|
|
429
|
+
// side bar controls are absolute within the containers, padding would not move them
|
|
430
|
+
...(statusBarClearance &&
|
|
431
|
+
!sideBar && {
|
|
432
|
+
headerLeftContainerStyle: { paddingLeft: statusBarClearance.left },
|
|
433
|
+
headerRightContainerStyle: { paddingRight: statusBarClearance.right },
|
|
434
|
+
}),
|
|
435
|
+
});
|
|
436
|
+
|
|
348
437
|
/**
|
|
349
438
|
* Side margin @react-navigation/elements Header adds to its content row
|
|
350
439
|
*/
|
|
@@ -410,6 +499,7 @@ export {
|
|
|
410
499
|
DuoMetrics,
|
|
411
500
|
HeaderMetrics,
|
|
412
501
|
getHeaderMargin,
|
|
502
|
+
getHeaderRowOptions,
|
|
413
503
|
useGridSystem,
|
|
414
504
|
useScreenLayout,
|
|
415
505
|
useSideBarItemStyle,
|