MenuToggle.tsx 1.9 KB

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