Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mastodon
GitHub Repository: mastodon/joinmastodon
Path: blob/main/components/MenuToggle.tsx
1006 views
1
import classNames from "classnames"
2
import { useEffect } from "react"
3
import { useIntl } from "react-intl"
4
5
export type MenuToggleProps = {
6
/** Open state of the toggle, controls HTML element's overflow as well */
7
open: boolean
8
/** Toggle's button click handler */
9
onClick: () => void
10
/** Misc. attributes (eg. aria-*) */
11
attributes: React.ComponentPropsWithoutRef<"button">
12
}
13
/**
14
* Mobile menu toggle
15
* Also controls scrollability of the page
16
*/
17
export const MenuToggle = ({ open, onClick, attributes }: MenuToggleProps) => {
18
const intl = useIntl()
19
useEffect(() => {
20
document.documentElement.classList.toggle("overflow-hidden", open)
21
document.documentElement.classList.toggle("md:overflow-auto", open)
22
}, [open])
23
return (
24
<button
25
onClick={onClick}
26
className="relative z-10 md:hidden"
27
{...attributes}
28
aria-label={intl.formatMessage({
29
id: "nav.toggle",
30
defaultMessage: "Toggle menu",
31
})}
32
>
33
<svg
34
width="27"
35
height="19"
36
viewBox="0 0 27 19"
37
className="overflow-visible"
38
>
39
<line
40
className={classNames(
41
"origin-center stroke-white transition-all",
42
open && "-translate-x-[5px] translate-y-[0.37rem] rotate-45"
43
)}
44
y1="1.5"
45
x2="27"
46
y2="1.5"
47
strokeWidth="3"
48
/>
49
<line
50
className={classNames(
51
"origin-center stroke-white transition-all",
52
open && "opacity-0"
53
)}
54
y1="9.50002"
55
x2="27"
56
y2="9.50002"
57
strokeWidth="3"
58
/>
59
<line
60
className={classNames(
61
"origin-center stroke-white transition-all",
62
open && "-translate-x-[5px] -translate-y-[0.37rem] -rotate-45"
63
)}
64
y1="17.5"
65
x2="27"
66
y2="17.5"
67
strokeWidth="3"
68
/>
69
</svg>
70
</button>
71
)
72
}
73
74
export default MenuToggle
75
76