Skip to content

Commit

Permalink
refactor: persist drawer state between route changes
Browse files Browse the repository at this point in the history
  • Loading branch information
datsfilipe committed Jul 26, 2024
1 parent ae58a91 commit 776ed31
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 25 deletions.
7 changes: 6 additions & 1 deletion src/app/ui/app.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { AppRouter } from '@app/lib/routes'
import { DrawerContextProvider } from '@features/drawer/lib/drawerContext'

function App() {
return <AppRouter />
return (
<DrawerContextProvider>
<AppRouter />
</DrawerContextProvider>
)
}

export default App
26 changes: 26 additions & 0 deletions src/features/drawer/lib/drawerContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useMediaQuery } from '@shared/lib/useMediaQuery'
import { createContext, useContext, useEffect, useState } from 'react'

type DrawerContextValue = {
isOpen: boolean
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>
}

export const DrawerContext = createContext<DrawerContextValue>({
isOpen: false,
setIsOpen: () => {}
})

export const DrawerContextProvider = ({ children }: { children: React.ReactNode }) => {
const [isOpen, setIsOpen] = useState<boolean>(true)

const isLargeScreen = useMediaQuery('(min-width: 1280px)')

useEffect(() => {
setIsOpen(isLargeScreen)
}, [isLargeScreen])

return <DrawerContext.Provider value={{ isOpen, setIsOpen }}>{children}</DrawerContext.Provider>
}

export const useDrawer = () => useContext(DrawerContext)
28 changes: 4 additions & 24 deletions src/features/drawer/ui/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
import { FaAngleLeft } from 'react-icons/fa6'
import { useEffect, useState } from 'react'

const useMediaQuery = (query: string) => {
const [matches, setMatches] = useState(false)
useEffect(() => {
const media = window.matchMedia(query)
if (media.matches !== matches) {
setMatches(media.matches)
}
const listener = () => {
setMatches(media.matches)
}
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}, [matches, query])
return matches
}
import { useEffect } from 'react'
import { useDrawer } from '../lib/drawerContext'

export default function Drawer(props: { children: React.ReactNode }) {
const [isOpen, setIsOpen] = useState(false)
const isLargeScreen = useMediaQuery('(min-width: 1280px)')

useEffect(() => {
setIsOpen(isLargeScreen)
}, [isLargeScreen])
const { isOpen, setIsOpen } = useDrawer()

useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
Expand All @@ -48,7 +28,7 @@ export default function Drawer(props: { children: React.ReactNode }) {

window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [])
}, [setIsOpen])

return (
<div className={`flex ${!isOpen ? '-ml-14' : 'mr-4'} min-h-[75dvh]`}>
Expand Down
17 changes: 17 additions & 0 deletions src/shared/lib/useMediaQuery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useState } from 'react'

export const useMediaQuery = (query: string) => {
const [matches, setMatches] = useState(true)
useEffect(() => {
const media = window.matchMedia(query)
if (media.matches !== matches) {
setMatches(media.matches)
}
const listener = () => {
setMatches(media.matches)
}
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}, [matches, query])
return matches
}

0 comments on commit 776ed31

Please sign in to comment.