Skip to content

Commit 94d90b5

Browse files
outsource settings effects
1 parent 0569c6d commit 94d90b5

File tree

3 files changed

+84
-56
lines changed

3 files changed

+84
-56
lines changed

src/components/UI/navigation/SettingsPopup.tsx

Lines changed: 9 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FC, useContext, useEffect, useRef, useState } from 'react'
1+
import { FC, useContext, useRef, useState } from 'react'
22
import {
33
ContextLanguage,
44
ContextSEOSearchText,
@@ -12,6 +12,8 @@ import Icon from '../Icon'
1212
import ProfilePicture from './ProfilePicture'
1313
import { getLanguageIndex } from '../../../helper/getLanguageIndex'
1414
import { setItemInStorage } from '../../../helper/setItemInStorage'
15+
import { useCloseSettingsPopup } from '../../../hooks/useCloseSettingsPopup'
16+
import { useSettingsPopupFocusTrap } from '../../../hooks/useSettingsPopupFocusTrap'
1517

1618
type SettingsPopupProps = {
1719
handleButtonKeyDown: (e: React.KeyboardEvent<HTMLButtonElement>) => void
@@ -176,61 +178,12 @@ const SettingsPopup: FC<SettingsPopupProps> = ({
176178
window.location.reload()
177179
}
178180

179-
useEffect(() => {
180-
const handleEscape = (event: KeyboardEvent) => {
181-
if (
182-
popupLanguageRef.current &&
183-
!popupLanguageRef.current.contains(event.target as Node) &&
184-
filterLanguageExpanded &&
185-
event.key === 'Escape'
186-
) {
187-
event.stopPropagation()
188-
setFilterLanguageExpanded(false)
189-
}
190-
}
191-
192-
if (filterLanguageExpanded) {
193-
document.addEventListener('keydown', handleEscape)
194-
} else {
195-
document.removeEventListener('keydown', handleEscape)
196-
}
197-
198-
return () => {
199-
document.removeEventListener('keydown', handleEscape)
200-
}
201-
}, [filterLanguageExpanded, setFilterLanguageExpanded])
202-
203-
useEffect(() => {
204-
if (filterLanguageExpanded) return
205-
206-
const buttons = popupRef.current?.querySelectorAll('button')
207-
if (!buttons || buttons.length === 0) return
208-
209-
const firstButton = buttons[0]
210-
const lastButton = buttons[buttons.length - 1]
211-
212-
const handleFocusTrap = (e: KeyboardEvent) => {
213-
if (e.key !== 'Tab') return
214-
215-
if (e.shiftKey) {
216-
if (document.activeElement === firstButton) {
217-
e.preventDefault()
218-
lastButton.focus()
219-
}
220-
} else {
221-
if (document.activeElement === lastButton) {
222-
e.preventDefault()
223-
firstButton.focus()
224-
}
225-
}
226-
}
227-
228-
document.addEventListener('keydown', handleFocusTrap)
229-
230-
return () => {
231-
document.removeEventListener('keydown', handleFocusTrap)
232-
}
233-
}, [filterLanguageExpanded, popupRef])
181+
useCloseSettingsPopup(
182+
filterLanguageExpanded,
183+
popupLanguageRef,
184+
setFilterLanguageExpanded
185+
)
186+
useSettingsPopupFocusTrap(filterLanguageExpanded, popupRef)
234187

235188
return (
236189
<div

src/hooks/useCloseSettingsPopup.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { useEffect } from 'react'
2+
3+
export const useCloseSettingsPopup = (
4+
filterLanguageExpanded: boolean,
5+
popupLanguageRef: React.MutableRefObject<HTMLDivElement | null>,
6+
setFilterLanguageExpanded: (value: React.SetStateAction<boolean>) => void
7+
) => {
8+
useEffect(() => {
9+
const handleEscape = (event: KeyboardEvent) => {
10+
if (
11+
popupLanguageRef.current &&
12+
!popupLanguageRef.current.contains(event.target as Node) &&
13+
filterLanguageExpanded &&
14+
event.key === 'Escape'
15+
) {
16+
event.stopPropagation()
17+
setFilterLanguageExpanded(false)
18+
}
19+
}
20+
21+
if (filterLanguageExpanded) {
22+
document.addEventListener('keydown', handleEscape)
23+
} else {
24+
document.removeEventListener('keydown', handleEscape)
25+
}
26+
27+
return () => {
28+
document.removeEventListener('keydown', handleEscape)
29+
}
30+
}, [filterLanguageExpanded, popupLanguageRef, setFilterLanguageExpanded])
31+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useEffect } from 'react'
2+
3+
export const useSettingsPopupFocusTrap = (
4+
filterLanguageExpanded: boolean,
5+
popupRef: React.MutableRefObject<HTMLDivElement | null>
6+
) => {
7+
useEffect(() => {
8+
if (filterLanguageExpanded) {
9+
return
10+
}
11+
12+
const buttons = popupRef.current?.querySelectorAll('button')
13+
if (!buttons || buttons.length === 0) {
14+
return
15+
}
16+
17+
const firstButton = buttons[0]
18+
const lastButton = buttons[buttons.length - 1]
19+
20+
const handleFocusTrap = (e: KeyboardEvent) => {
21+
if (e.key !== 'Tab') {
22+
return
23+
}
24+
25+
if (e.shiftKey) {
26+
if (document.activeElement === firstButton) {
27+
e.preventDefault()
28+
lastButton.focus()
29+
}
30+
} else {
31+
if (document.activeElement === lastButton) {
32+
e.preventDefault()
33+
firstButton.focus()
34+
}
35+
}
36+
}
37+
38+
document.addEventListener('keydown', handleFocusTrap)
39+
40+
return () => {
41+
document.removeEventListener('keydown', handleFocusTrap)
42+
}
43+
}, [filterLanguageExpanded, popupRef])
44+
}

0 commit comments

Comments
 (0)