From 973978098e6e4dc52454a0c119bccc0d3e31885a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 12 Jul 2024 12:17:30 +0200 Subject: [PATCH] Sidebar open/close improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- src/components/sidebar-menu.tsx | 51 ++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/components/sidebar-menu.tsx b/src/components/sidebar-menu.tsx index 3cd8e8c56..bcdc8f1b5 100644 --- a/src/components/sidebar-menu.tsx +++ b/src/components/sidebar-menu.tsx @@ -1,6 +1,6 @@ /* eslint-disable jsx-a11y/interactive-supports-focus */ import clsx from 'clsx'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { Link, NavLink } from 'react-router-dom'; @@ -84,7 +84,10 @@ const SidebarMenu: React.FC = (): JSX.Element | null => { const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count()); const draftCount = useAppSelector((state) => state.draft_statuses.size); const [sidebarVisible, setSidebarVisible] = useState(sidebarOpen); + const [touchStart, setTouchStart] = useState(0); + const [touchEnd, setTouchEnd] = useState(0); + const containerRef = React.useRef(null); const closeButtonRef = React.useRef(null); const [switcher, setSwitcher] = React.useState(false); @@ -120,15 +123,29 @@ const SidebarMenu: React.FC = (): JSX.Element | null => { ); - React.useEffect(() => { + const handleOutsideClick: React.MouseEventHandler = (e) => { + if ((e.target as HTMLElement).isSameNode(e.currentTarget)) handleClose(); + }; + + const handleKeyDown: React.KeyboardEventHandler = (e) => { + if (e.key === 'Escape') handleClose(); + }; + + const handleTouchStart: React.TouchEventHandler = (e) => setTouchStart(e.targetTouches[0].clientX); + const handleTouchMove: React.TouchEventHandler = (e) => setTouchEnd(e.targetTouches[0].clientX); + + const handleTouchEnd = () => { + if (touchStart - touchEnd > 100) { + handleClose(); + } + }; + + useEffect(() => { dispatch(fetchOwnAccounts()); }, []); - React.useEffect(() => { - // eslint-disable-next-line compat/compat - requestAnimationFrame(() => { - setSidebarVisible(sidebarOpen); - }); + useEffect(() => { + setTimeout(() => setSidebarVisible(sidebarOpen), sidebarOpen ? 0 : 150); }, [sidebarOpen]); return ( @@ -136,26 +153,34 @@ const SidebarMenu: React.FC = (): JSX.Element | null => { aria-expanded={sidebarOpen} className={ clsx({ - 'z-[1000]': sidebarOpen, - hidden: !sidebarOpen, + 'z-[1000]': sidebarOpen || sidebarVisible, + hidden: !(sidebarOpen || sidebarVisible), }) } + ref={containerRef} + onKeyDown={handleKeyDown} + onTouchStart={handleTouchStart} + onTouchMove={handleTouchMove} + onTouchEnd={handleTouchEnd} >
-
+