open sidebar on swipe (#1098)

This commit is contained in:
Athou
2024-01-10 19:42:45 +01:00
parent df68405fef
commit bbda35f868

View File

@@ -19,6 +19,7 @@ import { type ReactNode, Suspense, useEffect } from "react"
import Draggable from "react-draggable" import Draggable from "react-draggable"
import { TbMenu2, TbPlus, TbX } from "react-icons/tb" import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
import { Outlet } from "react-router-dom" import { Outlet } from "react-router-dom"
import { useSwipeable } from "react-swipeable"
import { tss } from "tss" import { tss } from "tss"
import useLocalStorage from "use-local-storage" import useLocalStorage from "use-local-storage"
@@ -111,83 +112,94 @@ export default function Layout(props: LayoutProps) {
</ActionIcon> </ActionIcon>
) )
const swipeHandlers = useSwipeable({
onSwiping: e => {
const threshold = document.documentElement.clientWidth / 6
if (e.absX > threshold) {
dispatch(setMobileMenuOpen(e.dir === "Right"))
}
},
})
if (loading) return <LoadingPage /> if (loading) return <LoadingPage />
return ( return (
<AppShell <Box {...swipeHandlers}>
header={{ height: Constants.layout.headerHeight }} <AppShell
navbar={{ header={{ height: Constants.layout.headerHeight }}
width: sidebarWidth, navbar={{
breakpoint: Constants.layout.mobileBreakpoint, width: sidebarWidth,
collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible }, breakpoint: Constants.layout.mobileBreakpoint,
}} collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible },
padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }} }}
> padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }}
<AppShell.Header id="header"> >
<OnMobile> <AppShell.Header id="header">
{mobileMenuOpen && ( <OnMobile>
<Group justify="space-between" p="md"> {mobileMenuOpen && (
<Box>{burger}</Box> <Group justify="space-between" p="md">
<Box> <Box>{burger}</Box>
<LogoAndTitle /> <Box>
</Box> <LogoAndTitle />
<Box>{addButton}</Box> </Box>
</Group> <Box>{addButton}</Box>
)} </Group>
{!mobileMenuOpen && ( )}
{!mobileMenuOpen && (
<Group p="md">
<Box>{burger}</Box>
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
</Group>
)}
</OnMobile>
<OnDesktop>
<Group p="md"> <Group p="md">
<Box>{burger}</Box> <Group justify="space-between" style={{ width: sidebarWidth - 16 }}>
<Box>
<LogoAndTitle />
</Box>
<Box>{addButton}</Box>
</Group>
<Box style={{ flexGrow: 1 }}>{props.header}</Box> <Box style={{ flexGrow: 1 }}>{props.header}</Box>
</Group> </Group>
)} </OnDesktop>
</OnMobile> </AppShell.Header>
<AppShell.Navbar id="sidebar" p={sidebarPadding}>
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
</AppShell.Section>
</AppShell.Navbar>
<OnDesktop> <OnDesktop>
<Group p="md"> <Draggable
<Group justify="space-between" style={{ width: sidebarWidth - 16 }}> axis="x"
<Box> defaultPosition={{
<LogoAndTitle /> x: sidebarWidth,
</Box> y: Constants.layout.headerHeight,
<Box>{addButton}</Box>
</Group>
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
</Group>
</OnDesktop>
</AppShell.Header>
<AppShell.Navbar id="sidebar" p={sidebarPadding}>
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
</AppShell.Section>
</AppShell.Navbar>
<OnDesktop>
<Draggable
axis="x"
defaultPosition={{
x: sidebarWidth,
y: Constants.layout.headerHeight,
}}
bounds={{
left: 120,
right: 1000,
}}
grid={[30, 30]}
onDrag={(_e, data) => setSidebarWidth(data.x)}
>
<Box
style={{
position: "fixed",
height: "100%",
width: "10px",
cursor: "ew-resize",
}} }}
></Box> bounds={{
</Draggable> left: 120,
</OnDesktop> right: 1000,
}}
grid={[30, 30]}
onDrag={(_e, data) => setSidebarWidth(data.x)}
>
<Box
style={{
position: "fixed",
height: "100%",
width: "10px",
cursor: "ew-resize",
}}
></Box>
</Draggable>
</OnDesktop>
<AppShell.Main id="content"> <AppShell.Main id="content">
<Suspense fallback={<Loader />}> <Suspense fallback={<Loader />}>
<AnnouncementDialog /> <AnnouncementDialog />
<Outlet /> <Outlet />
</Suspense> </Suspense>
</AppShell.Main> </AppShell.Main>
</AppShell> </AppShell>
</Box>
) )
} }