Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Highlight active Drawer Item #161

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function InnerApp() {
<SettingsGate>
<NavigationContainer linking={linking}>
<DrawerNavigation.Navigator
drawerContent={({ navigation }) => <Drawer navigation={navigation} />}
drawerContent={(props) => <Drawer {...props} />}
drawerStyle={initRender ? { width: 0 } : null}
>
<DrawerNavigation.Screen name="Root" component={RootNavigator} />
Expand Down
16 changes: 9 additions & 7 deletions src/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

import * as React from "react";
import { useSelector } from "react-redux";
import { DrawerNavigationProp } from "@react-navigation/drawer";
import { DrawerContentComponentProps } from "@react-navigation/drawer";
import { DrawerActionHelpers, NavigationHelpers } from "@react-navigation/native";
import { Image, Linking, View, StatusBar } from "react-native";
import { Divider, Drawer as PaperDrawer, Text, Paragraph } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
Expand All @@ -22,6 +23,7 @@ import LogoutDialog from "./components/LogoutDialog";
import * as C from "./constants";
import { useCredentials } from "./credentials";
import { RootStackParamList } from "./RootStackParamList";
import { getActiveRoute } from "./helpers";

type MenuItem = {
title: string;
Expand Down Expand Up @@ -97,17 +99,14 @@ function FingerprintDialog(props: { visible: boolean, onDismiss: () => void }) {
);
}

interface PropsType {
navigation: any;
}

export default function Drawer(props: PropsType) {
export default function Drawer(props: DrawerContentComponentProps) {
const [showFingerprint, setShowFingerprint] = React.useState(false);
const [showLogout, setShowLogout] = React.useState(false);
const navigation = props.navigation as DrawerNavigationProp<RootStackParamList, keyof RootStackParamList>;
const navigation = props.navigation as NavigationHelpers<RootStackParamList, any> & DrawerActionHelpers<RootStackParamList>;
const etebase = useCredentials();
const loggedIn = !!etebase;
const syncCount = useSelector((state: StoreState) => state.syncCount);
const activeRoute = getActiveRoute(props.state);

return (
<>
Expand All @@ -134,6 +133,7 @@ export default function Drawer(props: PropsType) {
navigation.closeDrawer();
navigation.navigate("Home");
}}
focused={activeRoute.name === "Home" || activeRoute.name === "Collection"}
icon="note-multiple"
/>
<Divider />
Expand All @@ -149,6 +149,7 @@ export default function Drawer(props: PropsType) {
navigation.closeDrawer();
navigation.navigate(menuItem.path);
}}
focused={activeRoute.name === menuItem.path}
icon={menuItem.icon}
/>
))}
Expand All @@ -168,6 +169,7 @@ export default function Drawer(props: PropsType) {
navigation.closeDrawer();
navigation.navigate("Invitations");
}}
focused={activeRoute.name === "Invitations"}
icon="email-outline"
/>
<DrawerItem
Expand Down
1 change: 1 addition & 0 deletions src/RootNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default React.memo(function RootNavigator() {
return (
<>
<Stack.Navigator
initialRouteName="AccountWizard"
screenOptions={{
header: (props) => <Appbar {...props} menuFallback />,
cardStyle: {
Expand Down
20 changes: 20 additions & 0 deletions src/css/state.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,24 @@
}
.state.dark:focus {
background-color: rgba(255,255,255,0.12);
}

.state.active.light {
background-color: rgba(0, 145, 234, 0.12);
}
.state.active.light:hover {
background-color: rgba(0, 145, 234, 0.16);
}
.state.active.light:focus {
background-color: rgba(0, 145, 234, 0.24);
}

.state.active.dark {
background-color: rgba(0, 145, 234, 0.12);
}
.state.active.dark:hover {
background-color: rgba(0, 145, 234, 0.16);
}
.state.active.dark:focus {
background-color: rgba(0, 145, 234, 0.24);
}
11 changes: 11 additions & 0 deletions src/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import * as React from "react";
import { AppState, AppStateStatus, Platform, useWindowDimensions } from "react-native";
import { NavigationState, PartialState } from "@react-navigation/native";
import * as Etebase from "etebase";

import { logger } from "./logging";
Expand Down Expand Up @@ -189,3 +190,13 @@ export function useDeviceBreakpoint(device: keyof typeof deviceBreakpoints) {

return breakpoint;
}

export function getActiveRoute(state: NavigationState | Omit<PartialState<NavigationState>, "stale">): { name: string, params?: any } {
const route = (typeof state.index === "number") ? state.routes[state.index] : state.routes[state.routes.length - 1];

if (route.state) {
return getActiveRoute(route.state);
}

return route;
}
1 change: 1 addition & 0 deletions src/widgets/Clickable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type ChildProps = {

type PropsType = {
applyToChild?: boolean;
active?: boolean;
renderChild: (props: ChildProps) => React.ReactElement;
};

Expand Down
5 changes: 3 additions & 2 deletions src/widgets/Clickable.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ type ChildProps = {

type PropsType = {
applyToChild?: boolean;
active?: boolean;
renderChild: (props: ChildProps) => React.ReactElement;
};

export default function Clickable(props: PropsType) {
const { applyToChild, renderChild } = props;
const { active, applyToChild, renderChild } = props;
const theme = useTheme();
const className = `state ${theme.dark ? "dark" : "light"}`;
const className = `state${active ? " active" : ""} ${theme.dark ? "dark" : "light"}`;

if (applyToChild) {
return renderChild({ className });
Expand Down
9 changes: 7 additions & 2 deletions src/widgets/DrawerItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,35 @@ import { DrawerItem as BaseDrawerItem } from "@react-navigation/drawer";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { useTheme } from "../theme";
import Clickable from "./Clickable";
import { Platform } from "react-native";

type PropsType = Omit<React.ComponentProps<typeof BaseDrawerItem>, "icon"> & {
disabled?: boolean;
icon: string;
};

export default function DrawerItem(props: PropsType) {
const { disabled, icon, onPress, to, ...rest } = props;
const { disabled, focused, icon, onPress, to, ...rest } = props;
const { colors } = useTheme();

return <Clickable
active={focused}
renderChild={(props) => (
<BaseDrawerItem
{...props}
activeTintColor={(disabled) ? colors.disabled : colors.active}
activeBackgroundColor={(Platform.OS === "web") ? "transparent" : undefined}
inactiveTintColor={(disabled) ? colors.disabled : colors.text}
icon={({ size }) => (
<MaterialCommunityIcons
name={icon}
color={(disabled) ? colors.disabled : colors.inactiveIcon}
color={(disabled) ? colors.disabled : ((focused) ? colors.activeIcon : colors.inactiveIcon)}
size={size}
/>
)}
to={(disabled) ? "" : to}
onPress={(disabled) ? () => null : onPress}
focused={focused}
{...rest}
/>
)}
Expand Down