mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-10 09:13:43 +08:00
feat: add an option to override safe area insets
This commit is contained in:
@@ -9483,7 +9483,14 @@ react-native-safe-area-context@^0.3.6:
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-0.3.6.tgz#666bf581b59aa49a9685aea4e76dfd6e1c8a8a52"
|
||||
integrity sha512-5wlaJplOlWxBNnjmCtY/FAlsgRDuoKzmLQzbWUw4NDuOa3H2uq1kTdqTWOw78Nzm5FRqGWe1ZSLWU9+nSaN+vA==
|
||||
|
||||
react-native-safe-area-view@0.14.6, react-native-safe-area-view@^0.12.0, react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6:
|
||||
react-native-safe-area-view@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.12.0.tgz#5c312f087300ecf82e8541c3eac25d560e147f22"
|
||||
integrity sha512-UrAXmBC4KNR5K2eczIDZgqceWyKsgG9gmWFerHCvoyApfei8ceBB9u/c//PWCpS5Gt8MRLTmX5jPtzdXo2yNqg==
|
||||
dependencies:
|
||||
hoist-non-react-statics "^2.3.1"
|
||||
|
||||
react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6:
|
||||
version "0.14.6"
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446"
|
||||
integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA==
|
||||
|
||||
@@ -101,6 +101,7 @@ export type HeaderOptions = {
|
||||
export type HeaderProps = {
|
||||
mode: 'float' | 'screen';
|
||||
layout: Layout;
|
||||
insets: EdgeInsets;
|
||||
scene: HeaderScene;
|
||||
previous?: HeaderScene;
|
||||
navigation: NavigationStackProp;
|
||||
@@ -129,6 +130,12 @@ export type NavigationStackOptions = HeaderOptions &
|
||||
onTransitionStart?: (props: TransitionCallbackProps) => void;
|
||||
onTransitionEnd?: (props: TransitionCallbackProps) => void;
|
||||
gestureVelocityImpact?: number;
|
||||
safeAreaInsets?: {
|
||||
top?: number;
|
||||
right?: number;
|
||||
bottom?: number;
|
||||
left?: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type NavigationStackConfig = {
|
||||
|
||||
@@ -9,6 +9,7 @@ export default class Header extends React.PureComponent<HeaderProps> {
|
||||
scene,
|
||||
previous,
|
||||
layout,
|
||||
insets,
|
||||
navigation,
|
||||
styleInterpolator,
|
||||
} = this.props;
|
||||
@@ -42,6 +43,7 @@ export default class Header extends React.PureComponent<HeaderProps> {
|
||||
<HeaderSegment
|
||||
{...options}
|
||||
layout={layout}
|
||||
insets={insets}
|
||||
scene={scene}
|
||||
title={title}
|
||||
leftLabel={leftLabel}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
|
||||
import { NavigationContext, NavigationRoute } from 'react-navigation';
|
||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
||||
import {
|
||||
Layout,
|
||||
HeaderScene,
|
||||
@@ -13,6 +14,7 @@ import { forStatic } from '../../TransitionConfigs/HeaderStyleInterpolators';
|
||||
export type Props = {
|
||||
mode: 'float' | 'screen';
|
||||
layout: Layout;
|
||||
insets: EdgeInsets;
|
||||
scenes: Array<HeaderScene | undefined>;
|
||||
navigation: NavigationStackProp;
|
||||
getPreviousRoute: (props: {
|
||||
@@ -30,6 +32,7 @@ export default function HeaderContainer({
|
||||
mode,
|
||||
scenes,
|
||||
layout,
|
||||
insets,
|
||||
navigation,
|
||||
getPreviousRoute,
|
||||
onContentHeightChange,
|
||||
@@ -84,6 +87,7 @@ export default function HeaderContainer({
|
||||
const props = {
|
||||
mode,
|
||||
layout,
|
||||
insets,
|
||||
scene,
|
||||
previous,
|
||||
navigation: scene.descriptor.navigation as NavigationStackProp,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import { SafeAreaContext, EdgeInsets } from 'react-native-safe-area-context';
|
||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
||||
import HeaderTitle from './HeaderTitle';
|
||||
import HeaderBackButton from './HeaderBackButton';
|
||||
import HeaderBackground from './HeaderBackground';
|
||||
@@ -27,6 +27,7 @@ export type Scene<T> = {
|
||||
|
||||
type Props = HeaderOptions & {
|
||||
layout: Layout;
|
||||
insets: EdgeInsets;
|
||||
onGoBack?: () => void;
|
||||
title?: React.ReactNode;
|
||||
leftLabel?: string;
|
||||
@@ -39,13 +40,6 @@ type State = {
|
||||
leftLabelLayout?: Layout;
|
||||
};
|
||||
|
||||
const DEFAULT_INSETS = {
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
};
|
||||
|
||||
const warnIfHeaderStylesDefined = (styles: { [key: string]: any }) => {
|
||||
Object.keys(styles).forEach(styleProp => {
|
||||
const value = styles[styleProp];
|
||||
@@ -87,10 +81,6 @@ export const getDefaultHeaderHeight = (
|
||||
};
|
||||
|
||||
export default class HeaderSegment extends React.Component<Props, State> {
|
||||
static contextType = SafeAreaContext;
|
||||
|
||||
context!: EdgeInsets | null;
|
||||
|
||||
state: State = {};
|
||||
|
||||
private handleTitleLayout = (e: LayoutChangeEvent) => {
|
||||
@@ -147,6 +137,7 @@ export default class HeaderSegment extends React.Component<Props, State> {
|
||||
const {
|
||||
scene,
|
||||
layout,
|
||||
insets,
|
||||
title: currentTitle,
|
||||
leftLabel: previousTitle,
|
||||
onGoBack,
|
||||
@@ -197,12 +188,10 @@ export default class HeaderSegment extends React.Component<Props, State> {
|
||||
previousTitle ? leftLabelLayout : undefined
|
||||
);
|
||||
|
||||
const insets = this.context || DEFAULT_INSETS;
|
||||
|
||||
const statusBarHeight = insets.top;
|
||||
|
||||
const {
|
||||
height = getDefaultHeaderHeight(layout, this.context),
|
||||
height = getDefaultHeaderHeight(layout, insets),
|
||||
minHeight,
|
||||
maxHeight,
|
||||
backgroundColor,
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
PanGestureHandler,
|
||||
State as GestureState,
|
||||
} from 'react-native-gesture-handler';
|
||||
import { SafeAreaContext, EdgeInsets } from 'react-native-safe-area-context';
|
||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
||||
import {
|
||||
TransitionSpec,
|
||||
CardStyleInterpolator,
|
||||
@@ -34,6 +34,7 @@ type Props = ViewProps & {
|
||||
next?: Animated.Node<number>;
|
||||
current: Animated.Value<number>;
|
||||
layout: Layout;
|
||||
insets: EdgeInsets;
|
||||
gestureDirection: 'horizontal' | 'vertical' | 'vertical-inverted';
|
||||
onOpen: (isFinished: boolean) => void;
|
||||
onClose: (isFinished: boolean) => void;
|
||||
@@ -229,13 +230,6 @@ function transformTimingConfigToAnimatedValues(
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_INSETS: EdgeInsets = {
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
};
|
||||
|
||||
export default class Card extends React.Component<Props> {
|
||||
static defaultProps = {
|
||||
overlayEnabled: Platform.OS !== 'ios',
|
||||
@@ -244,10 +238,6 @@ export default class Card extends React.Component<Props> {
|
||||
gestureVelocityImpact: GESTURE_VELOCITY_IMPACT,
|
||||
};
|
||||
|
||||
static contextType = SafeAreaContext;
|
||||
|
||||
context!: EdgeInsets | null;
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
const {
|
||||
layout,
|
||||
@@ -407,7 +397,10 @@ export default class Card extends React.Component<Props> {
|
||||
this.props.current,
|
||||
this.props.next,
|
||||
this.props.layout,
|
||||
this.context || DEFAULT_INSETS
|
||||
this.props.insets.top,
|
||||
this.props.insets.right,
|
||||
this.props.insets.bottom,
|
||||
this.props.insets.left
|
||||
);
|
||||
};
|
||||
|
||||
@@ -716,7 +709,10 @@ export default class Card extends React.Component<Props> {
|
||||
current: Animated.Node<number>,
|
||||
next: Animated.Node<number> | undefined,
|
||||
layout: Layout,
|
||||
insets: EdgeInsets
|
||||
insetTop: number,
|
||||
insetRight: number,
|
||||
insetBottom: number,
|
||||
insetLeft: number
|
||||
) =>
|
||||
styleInterpolator({
|
||||
index,
|
||||
@@ -726,7 +722,12 @@ export default class Card extends React.Component<Props> {
|
||||
layouts: {
|
||||
screen: layout,
|
||||
},
|
||||
insets,
|
||||
insets: {
|
||||
top: insetTop,
|
||||
right: insetRight,
|
||||
bottom: insetBottom,
|
||||
left: insetLeft,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
@@ -740,7 +741,10 @@ export default class Card extends React.Component<Props> {
|
||||
this.props.current,
|
||||
this.props.next,
|
||||
this.props.layout,
|
||||
this.context || DEFAULT_INSETS
|
||||
this.props.insets.top,
|
||||
this.props.insets.right,
|
||||
this.props.insets.bottom,
|
||||
this.props.insets.left
|
||||
);
|
||||
|
||||
private gestureActivationCriteria() {
|
||||
@@ -797,6 +801,7 @@ export default class Card extends React.Component<Props> {
|
||||
current,
|
||||
next,
|
||||
layout,
|
||||
insets,
|
||||
overlayEnabled,
|
||||
shadowEnabled,
|
||||
gestureEnabled,
|
||||
@@ -814,7 +819,10 @@ export default class Card extends React.Component<Props> {
|
||||
current,
|
||||
next,
|
||||
layout,
|
||||
this.context || DEFAULT_INSETS
|
||||
insets.top,
|
||||
insets.right,
|
||||
insets.bottom,
|
||||
insets.left
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ type ProgressValues = {
|
||||
|
||||
type Props = {
|
||||
mode: 'card' | 'modal';
|
||||
insets: EdgeInsets | null;
|
||||
insets: EdgeInsets;
|
||||
navigation: NavigationStackProp;
|
||||
descriptors: SceneDescriptorMap;
|
||||
routes: NavigationRoute[];
|
||||
@@ -300,6 +300,7 @@ export default class Stack extends React.Component<Props, State> {
|
||||
render() {
|
||||
const {
|
||||
mode,
|
||||
insets,
|
||||
descriptors,
|
||||
navigation,
|
||||
routes,
|
||||
@@ -333,6 +334,13 @@ export default class Stack extends React.Component<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
const {
|
||||
top = insets.top,
|
||||
right = insets.right,
|
||||
bottom = insets.bottom,
|
||||
left = insets.left,
|
||||
} = focusedOptions.safeAreaInsets || {};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<MaybeScreenContainer
|
||||
@@ -367,6 +375,7 @@ export default class Stack extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
const {
|
||||
safeAreaInsets,
|
||||
header,
|
||||
headerShown,
|
||||
headerTransparent,
|
||||
@@ -416,6 +425,13 @@ export default class Stack extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
top: safeAreaInsetTop = insets.top,
|
||||
right: safeAreaInsetRight = insets.right,
|
||||
bottom: safeAreaInsetBottom = insets.bottom,
|
||||
left: safeAreaInsetLeft = insets.left,
|
||||
} = safeAreaInsets || {};
|
||||
|
||||
return (
|
||||
<MaybeScreen
|
||||
key={route.key}
|
||||
@@ -434,6 +450,10 @@ export default class Stack extends React.Component<Props, State> {
|
||||
scene={scene}
|
||||
previousScene={scenes[index - 1]}
|
||||
navigation={navigation}
|
||||
safeAreaInsetTop={safeAreaInsetTop}
|
||||
safeAreaInsetRight={safeAreaInsetRight}
|
||||
safeAreaInsetBottom={safeAreaInsetBottom}
|
||||
safeAreaInsetLeft={safeAreaInsetLeft}
|
||||
cardTransparent={cardTransparent}
|
||||
cardOverlayEnabled={cardOverlayEnabled}
|
||||
cardShadowEnabled={cardShadowEnabled}
|
||||
@@ -470,6 +490,7 @@ export default class Stack extends React.Component<Props, State> {
|
||||
? renderHeader({
|
||||
mode: 'float',
|
||||
layout,
|
||||
insets: { top, right, bottom, left },
|
||||
scenes,
|
||||
navigation,
|
||||
getPreviousRoute,
|
||||
|
||||
@@ -22,6 +22,10 @@ type Props = TransitionPreset & {
|
||||
previousScene?: HeaderScene;
|
||||
scene: HeaderScene;
|
||||
navigation: NavigationStackProp;
|
||||
safeAreaInsetTop: number;
|
||||
safeAreaInsetRight: number;
|
||||
safeAreaInsetBottom: number;
|
||||
safeAreaInsetLeft: number;
|
||||
cardTransparent?: boolean;
|
||||
cardOverlayEnabled?: boolean;
|
||||
cardShadowEnabled?: boolean;
|
||||
@@ -102,6 +106,10 @@ export default class StackItem extends React.PureComponent<Props> {
|
||||
navigation,
|
||||
scene,
|
||||
previousScene,
|
||||
safeAreaInsetTop,
|
||||
safeAreaInsetRight,
|
||||
safeAreaInsetBottom,
|
||||
safeAreaInsetLeft,
|
||||
cardTransparent,
|
||||
cardOverlayEnabled,
|
||||
cardShadowEnabled,
|
||||
@@ -124,6 +132,13 @@ export default class StackItem extends React.PureComponent<Props> {
|
||||
gestureVelocityImpact,
|
||||
} = this.props;
|
||||
|
||||
const insets = {
|
||||
top: safeAreaInsetTop,
|
||||
right: safeAreaInsetRight,
|
||||
bottom: safeAreaInsetBottom,
|
||||
left: safeAreaInsetLeft,
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
index={index}
|
||||
@@ -131,6 +146,7 @@ export default class StackItem extends React.PureComponent<Props> {
|
||||
transparent={cardTransparent}
|
||||
gestureDirection={gestureDirection}
|
||||
layout={layout}
|
||||
insets={insets}
|
||||
current={current}
|
||||
next={scene.progress.next}
|
||||
closing={closing}
|
||||
@@ -165,6 +181,7 @@ export default class StackItem extends React.PureComponent<Props> {
|
||||
? renderHeader({
|
||||
mode: 'screen',
|
||||
layout,
|
||||
insets,
|
||||
scenes: [previousScene, scene],
|
||||
navigation,
|
||||
getPreviousRoute,
|
||||
|
||||
@@ -43,6 +43,13 @@ type State = {
|
||||
descriptors: SceneDescriptorMap;
|
||||
};
|
||||
|
||||
const DEFAULT_INSETS = {
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
};
|
||||
|
||||
class StackView extends React.Component<Props, State> {
|
||||
static getDerivedStateFromProps(
|
||||
props: Readonly<Props>,
|
||||
@@ -364,7 +371,7 @@ class StackView extends React.Component<Props, State> {
|
||||
{insets => (
|
||||
<Stack
|
||||
mode={mode}
|
||||
insets={insets}
|
||||
insets={insets || DEFAULT_INSETS}
|
||||
getPreviousRoute={this.getPreviousRoute}
|
||||
getGesturesEnabled={this.getGesturesEnabled}
|
||||
routes={routes}
|
||||
|
||||
Reference in New Issue
Block a user