Skip to content

Commit

Permalink
refactor: move drawerContentOptions to options
Browse files Browse the repository at this point in the history
BREAKING CHANGE:  This commit moves options from `drawerContentOptions` to regular `options` in order to reduce confusion between the two, as well as to make it more flexible to configure the drawer on a per screen basis.
  • Loading branch information
satya164 committed Nov 19, 2020
1 parent 852f2f0 commit 15e5678
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 150 deletions.
15 changes: 8 additions & 7 deletions example/src/Screens/MasterDetail.tsx
Expand Up @@ -11,7 +11,6 @@ import {
DrawerScreenProps,
DrawerContent,
DrawerContentComponentProps,
DrawerContentOptions,
} from '@react-navigation/drawer';
import type { StackScreenProps } from '@react-navigation/stack';
import Article from '../Shared/Article';
Expand Down Expand Up @@ -91,9 +90,7 @@ const AlbumsScreen = ({
);
};

const CustomDrawerContent = (
props: DrawerContentComponentProps<DrawerContentOptions>
) => {
const CustomDrawerContent = (props: DrawerContentComponentProps) => {
const { colors } = useTheme();
const navigation = useNavigation();

Expand Down Expand Up @@ -126,10 +123,14 @@ export default function DrawerScreen({ navigation, ...rest }: Props) {
return (
<Drawer.Navigator
openByDefault
drawerType={isLargeScreen ? 'permanent' : 'back'}
drawerStyle={isLargeScreen ? null : { width: '100%' }}
overlayColor="transparent"
drawerContent={(props) => <CustomDrawerContent {...props} />}
screenOptions={{
headerShown: false,
drawerType: isLargeScreen ? 'permanent' : 'back',
drawerStyle: isLargeScreen ? null : { width: '100%' },
drawerContentContainerStyle: { paddingTop: 4 },
overlayColor: 'transparent',
}}
{...rest}
>
<Drawer.Screen name="Article" component={ArticleScreen} />
Expand Down
4 changes: 3 additions & 1 deletion example/src/index.tsx
Expand Up @@ -285,7 +285,9 @@ export default function App() {
>
{() => (
<Drawer.Navigator
drawerType={isLargeScreen ? 'permanent' : undefined}
screenOptions={{
drawerType: isLargeScreen ? 'permanent' : undefined,
}}
>
<Drawer.Screen
name="Examples"
Expand Down
1 change: 0 additions & 1 deletion packages/drawer/src/index.tsx
Expand Up @@ -27,6 +27,5 @@ export type {
DrawerNavigationOptions,
DrawerNavigationProp,
DrawerScreenProps,
DrawerContentOptions,
DrawerContentComponentProps,
} from './types';
202 changes: 107 additions & 95 deletions packages/drawer/src/types.tsx
Expand Up @@ -20,51 +20,7 @@ export type Scene = {

export type Layout = { width: number; height: number };

export type DrawerNavigationConfig<T = DrawerContentOptions> = {
/**
* Position of the drawer on the screen. Defaults to `left`.
*/
drawerPosition?: 'left' | 'right';
/**
* Type of the drawer. It determines how the drawer looks and animates.
* - `front`: Traditional drawer which covers the screen with a overlay behind it.
* - `back`: The drawer is revealed behind the screen on swipe.
* - `slide`: Both the screen and the drawer slide on swipe to reveal the drawer.
* - `permanent`: A permanent drawer is shown as a sidebar.
*/
drawerType?: 'front' | 'back' | 'slide' | 'permanent';
/**
* How far from the edge of the screen the swipe gesture should activate.
* Not supported on Web.
*/
edgeWidth?: number;
/**
* Whether the statusbar should be hidden when the drawer is pulled or opens,
*/
hideStatusBar?: boolean;
/**
* Whether the keyboard should be dismissed when the swipe gesture begins.
* Defaults to `'on-drag'`. Set to `'none'` to disable keyboard handling.
*/
keyboardDismissMode?: 'on-drag' | 'none';
/**
* Minimum swipe distance threshold that should activate opening the drawer.
*/
minSwipeDistance?: number;
/**
* Color of the overlay to be displayed on top of the content view when drawer gets open.
* The opacity is animated from `0` to `1` when the drawer opens.
*/
overlayColor?: string;
/**
* Animation of the statusbar when hiding it. use in combination with `hideStatusBar`.
*/
statusBarAnimation?: 'slide' | 'none' | 'fade';
/**
* Props to pass to the underlying pan gesture handler.
* Not supported on Web.
*/
gestureHandlerProps?: PanGestureHandlerProperties;
export type DrawerNavigationConfig = {
/**
* Whether the screens should render the first time they are accessed. Defaults to `true`.
* Set it to `false` if you want to render all screens on initial render.
Expand All @@ -74,20 +30,7 @@ export type DrawerNavigationConfig<T = DrawerContentOptions> = {
* Function that returns React element to render as the content of the drawer, for example, navigation items.
* Defaults to `DrawerContent`.
*/
drawerContent?: (props: DrawerContentComponentProps<T>) => React.ReactNode;
/**
* Options for the content component which will be passed as props.
*/
drawerContentOptions?: T;
/**
* Style object for the component wrapping the screen content.
*/
sceneContainerStyle?: StyleProp<ViewStyle>;
/**
* Style object for the drawer component.
* You can pass a custom background color for a drawer or a custom width here.
*/
drawerStyle?: StyleProp<ViewStyle>;
drawerContent?: (props: DrawerContentComponentProps) => React.ReactNode;
/**
* Whether inactive screens should be detached from the view hierarchy to save memory.
* Make sure to call `enableScreens` from `react-native-screens` to make it work.
Expand Down Expand Up @@ -203,6 +146,87 @@ export type DrawerNavigationOptions = DrawerHeaderOptions & {
focused: boolean;
}) => React.ReactNode;

/**
* Color for the icon and label in the active item in the drawer.
*/
drawerActiveTintColor?: string;

/**
* Background color for the active item in the drawer.
*/
drawerActiveBackgroundColor?: string;

/**
* Color for the icon and label in the inactive items in the drawer.
*/
drawerInactiveTintColor?: string;

/**
* Background color for the inactive items in the drawer.
*/
drawerInactiveBackgroundColor?: string;

/**
* Style object for the single item, which can contain an icon and/or a label.
*/
drawerItemStyle?: StyleProp<ViewStyle>;

/**
* Style object to apply to the `Text` inside content section which renders a label.
*/
drawerLabelStyle?: StyleProp<TextStyle>;

/**
* Style object for the content section.
*/
drawerContentContainerStyle?: StyleProp<ViewStyle>;

/**
* Style object for the wrapper view.
*/
drawerContentStyle?: StyleProp<ViewStyle>;

/**
* Style object for the drawer component.
* You can pass a custom background color for a drawer or a custom width here.
*/
drawerStyle?: StyleProp<ViewStyle>;

/**
* Position of the drawer on the screen. Defaults to `left`.
*/
drawerPosition?: 'left' | 'right';

/**
* Type of the drawer. It determines how the drawer looks and animates.
* - `front`: Traditional drawer which covers the screen with a overlay behind it.
* - `back`: The drawer is revealed behind the screen on swipe.
* - `slide`: Both the screen and the drawer slide on swipe to reveal the drawer.
* - `permanent`: A permanent drawer is shown as a sidebar.
*/
drawerType?: 'front' | 'back' | 'slide' | 'permanent';

/**
* Whether the statusbar should be hidden when the drawer is pulled or opens,
*/
drawerHideStatusBarOnOpen?: boolean;

/**
* Animation of the statusbar when hiding it. use in combination with `drawerHideStatusBarOnOpen`.
*/
drawerStatusBarAnimation?: 'slide' | 'none' | 'fade';

/**
* Color of the overlay to be displayed on top of the content view when drawer gets open.
* The opacity is animated from `0` to `1` when the drawer opens.
*/
overlayColor?: string;

/**
* Style object for the component wrapping the screen content.
*/
sceneContainerStyle?: StyleProp<ViewStyle>;

/**
* Whether you can use gestures to open or close the drawer.
* Setting this to `false` disables swipe gestures as well as tap on overlay to close.
Expand All @@ -212,21 +236,44 @@ export type DrawerNavigationOptions = DrawerHeaderOptions & {
*/
gestureEnabled?: boolean;

/**
* Props to pass to the underlying pan gesture handler.
* Not supported on Web.
*/
gestureHandlerProps?: PanGestureHandlerProperties;

/**
* Whether you can use swipe gestures to open or close the drawer.
* Defaults to `true`.
* Not supported on Web.
*/
swipeEnabled?: boolean;

/**
* How far from the edge of the screen the swipe gesture should activate.
* Not supported on Web.
*/
swipeEdgeWidth?: number;

/**
* Minimum swipe distance threshold that should activate opening the drawer.
*/
swipeMinDistance?: number;

/**
* Whether the keyboard should be dismissed when the swipe gesture begins.
* Defaults to `'on-drag'`. Set to `'none'` to disable keyboard handling.
*/
keyboardDismissMode?: 'on-drag' | 'none';

/**
* Whether this screen should be unmounted when navigating away from it.
* Defaults to `false`.
*/
unmountOnBlur?: boolean;
};

export type DrawerContentComponentProps<T = DrawerContentOptions> = T & {
export type DrawerContentComponentProps = {
state: DrawerNavigationState<ParamListBase>;
navigation: DrawerNavigationHelpers;
descriptors: DrawerDescriptorMap;
Expand All @@ -237,41 +284,6 @@ export type DrawerContentComponentProps<T = DrawerContentOptions> = T & {
progress: Animated.Node<number>;
};

export type DrawerContentOptions = {
/**
* Color for the icon and label in the active item in the drawer.
*/
activeTintColor?: string;
/**
* Background color for the active item in the drawer.
*/
activeBackgroundColor?: string;
/**
* Color for the icon and label in the inactive items in the drawer.
*/
inactiveTintColor?: string;
/**
* Background color for the inactive items in the drawer.
*/
inactiveBackgroundColor?: string;
/**
* Style object for the single item, which can contain an icon and/or a label.
*/
itemStyle?: StyleProp<ViewStyle>;
/**
* Style object to apply to the `Text` inside content section which renders a label.
*/
labelStyle?: StyleProp<TextStyle>;
/**
* Style object for the content section.
*/
contentContainerStyle?: StyleProp<ViewStyle>;
/**
* Style object for the wrapper view.
*/
style?: StyleProp<ViewStyle>;
};

export type DrawerHeaderProps = {
/**
* Layout of the screen.
Expand Down
9 changes: 6 additions & 3 deletions packages/drawer/src/views/Drawer.tsx
Expand Up @@ -89,7 +89,7 @@ type Props = {
swipeEdgeWidth: number;
swipeDistanceThreshold?: number;
swipeVelocityThreshold: number;
hideStatusBar: boolean;
hideStatusBarOnOpen: boolean;
statusBarAnimation: 'slide' | 'none' | 'fade';
overlayStyle?: StyleProp<ViewStyle>;
drawerStyle?: StyleProp<ViewStyle>;
Expand Down Expand Up @@ -129,7 +129,7 @@ export default class DrawerView extends React.Component<Props> {
drawerType,
swipeDistanceThreshold,
swipeVelocityThreshold,
hideStatusBar,
hideStatusBarOnOpen: hideStatusBar,
} = this.props;

if (
Expand Down Expand Up @@ -554,7 +554,10 @@ export default class DrawerView extends React.Component<Props> {
};

private toggleStatusBar = (hidden: boolean) => {
const { hideStatusBar, statusBarAnimation } = this.props;
const {
hideStatusBarOnOpen: hideStatusBar,
statusBarAnimation,
} = this.props;

if (hideStatusBar && this.isStatusBarHidden !== hidden) {
this.isStatusBarHidden = hidden;
Expand Down
18 changes: 15 additions & 3 deletions packages/drawer/src/views/DrawerContent.tsx
Expand Up @@ -3,10 +3,22 @@ import DrawerItemList from './DrawerItemList';
import DrawerContentScrollView from './DrawerContentScrollView';
import type { DrawerContentComponentProps } from '../types';

export default function DrawerContent(props: DrawerContentComponentProps) {
export default function DrawerContent({
descriptors,
state,
...rest
}: DrawerContentComponentProps) {
const { drawerContentStyle, drawerContentContainerStyle } = descriptors[
state.routes[state.index].key
].options;

return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerContentScrollView
{...rest}
contentContainerStyle={drawerContentContainerStyle}
style={drawerContentStyle}
>
<DrawerItemList descriptors={descriptors} state={state} {...rest} />
</DrawerContentScrollView>
);
}

0 comments on commit 15e5678

Please sign in to comment.