Просмотр исходного кода

improve hover and drag behavior

Yuki Takei 4 лет назад
Родитель
Сommit
e90e24c4c4
1 измененных файлов с 36 добавлено и 38 удалено
  1. 36 38
      packages/app/src/components/Sidebar.tsx

+ 36 - 38
packages/app/src/components/Sidebar.tsx

@@ -102,6 +102,11 @@ const Sidebar: FC<Props> = (props: Props) => {
   const { data: isCollapsed, mutate: mutateSidebarCollapsed } = useSidebarCollapsed();
   const { data: isResizeDisabled, mutate: mutateSidebarResizeDisabled } = useSidebarResizeDisabled();
 
+  const [isHover, setHover] = useState(false);
+  const [isDragging, setDrag] = useState(false);
+  const [isMounted, setMounted] = useState(false);
+
+  const isResizableByDrag = !isDrawerMode && (!isCollapsed || isHover);
   /**
    * hack and override UIController.storeState
    *
@@ -169,8 +174,6 @@ const Sidebar: FC<Props> = (props: Props) => {
     mutateDrawerOpened(false, false);
   }, [mutateDrawerOpened]);
 
-  const [isMounted, setMounted] = useState(false);
-
   useEffect(() => {
     // this.hackUIController();
     setMounted(true);
@@ -180,9 +183,6 @@ const Sidebar: FC<Props> = (props: Props) => {
     toggleDrawerMode(isDrawerMode);
   }, [isDrawerMode, toggleDrawerMode]);
 
-  const [isHover, setHover] = useState(false);
-  const [isDragging, setDrag] = useState(false);
-
   const resizableContainer = useRef<HTMLDivElement>(null);
   const setContentWidth = useCallback((newWidth) => {
     if (resizableContainer.current == null) {
@@ -192,22 +192,22 @@ const Sidebar: FC<Props> = (props: Props) => {
   }, []);
 
   const hoverOnResizableContainerHandler = useCallback(() => {
-    if (!isCollapsed || isDrawerMode) {
+    if (!isCollapsed || isDrawerMode || isDragging) {
       return;
     }
 
     setHover(true);
     setContentWidth(currentProductNavWidth);
-  }, [isCollapsed, isDrawerMode, setContentWidth, currentProductNavWidth]);
+  }, [isCollapsed, isDrawerMode, isDragging, setContentWidth, currentProductNavWidth]);
 
   const hoverOutHandler = useCallback(() => {
-    if (!isCollapsed || isDrawerMode) {
+    if (!isCollapsed || isDrawerMode || isDragging) {
       return;
     }
 
     setHover(false);
     setContentWidth(sidebarMinimizeWidth);
-  }, [isCollapsed, isDrawerMode, setContentWidth]);
+  }, [isCollapsed, isDragging, isDrawerMode, setContentWidth]);
 
   const toggleNavigationBtnClickHandler = useCallback(() => {
     const newValue = !isCollapsed;
@@ -224,16 +224,15 @@ const Sidebar: FC<Props> = (props: Props) => {
     }
   }, [currentProductNavWidth, isCollapsed, setContentWidth]);
 
-  const draggableAreaMoveHandler = useCallback((event) => {
-    if (isDragging) {
-      event.preventDefault();
-      const newWidth = event.pageX - 60;
-      if (resizableContainer.current != null) {
-        setContentWidth(newWidth);
-        resizableContainer.current.classList.add('dragging');
-      }
+  const draggableAreaMoveHandler = useCallback((event: MouseEvent) => {
+    event.preventDefault();
+
+    const newWidth = event.pageX - 60;
+    if (resizableContainer.current != null) {
+      setContentWidth(newWidth);
+      resizableContainer.current.classList.add('dragging');
     }
-  }, [isDragging, setContentWidth]);
+  }, [setContentWidth]);
 
   const dragableAreaMouseUpHandler = useCallback(() => {
     if (resizableContainer.current == null) {
@@ -244,7 +243,7 @@ const Sidebar: FC<Props> = (props: Props) => {
 
     if (resizableContainer.current.clientWidth < sidebarMinWidth) {
       // force collapsed
-      mutateSidebarCollapsed(true, false);
+      mutateSidebarCollapsed(true);
       mutateProductNavWidth(sidebarMinWidth, false);
       scheduleToPutUserUISettings({ isSidebarCollapsed: true, currentProductNavWidth: sidebarMinWidth });
     }
@@ -256,34 +255,35 @@ const Sidebar: FC<Props> = (props: Props) => {
 
     resizableContainer.current.classList.remove('dragging');
 
-    document.removeEventListener('mousemove', draggableAreaMoveHandler);
-    document.removeEventListener('mouseup', dragableAreaMouseUpHandler);
+  }, [mutateProductNavWidth, mutateSidebarCollapsed]);
 
-  }, [draggableAreaMoveHandler, mutateProductNavWidth, mutateSidebarCollapsed]);
-
-  const dragableAreaClickHandler = useCallback(() => {
-    if (isCollapsed || isDrawerMode) {
+  const dragableAreaMouseDownHandler = useCallback((event: MouseEvent) => {
+    if (!isResizableByDrag) {
       return;
     }
+
+    event.preventDefault();
+
     setDrag(true);
-  }, [isCollapsed, isDrawerMode]);
 
-  useEffect(() => {
-    document.addEventListener('mousemove', draggableAreaMoveHandler);
-    document.addEventListener('mouseup', dragableAreaMouseUpHandler);
-    // cleanup
-    return function cleanup() {
+    const removeEventListeners = () => {
       document.removeEventListener('mousemove', draggableAreaMoveHandler);
       document.removeEventListener('mouseup', dragableAreaMouseUpHandler);
+      document.removeEventListener('mouseup', removeEventListeners);
     };
-  }, [draggableAreaMoveHandler, dragableAreaMouseUpHandler]);
+
+    document.addEventListener('mousemove', draggableAreaMoveHandler);
+    document.addEventListener('mouseup', dragableAreaMouseUpHandler);
+    document.addEventListener('mouseup', removeEventListeners);
+
+  }, [dragableAreaMouseUpHandler, draggableAreaMoveHandler, isResizableByDrag]);
 
   return (
     <>
       <div className={`grw-sidebar d-print-none ${isDrawerMode ? 'grw-sidebar-drawer' : ''} ${isDrawerOpened ? 'open' : ''}`}>
         <div className="data-layout-container">
-          <div className="navigation">
-            <div className="grw-navigation-wrap" onMouseLeave={hoverOutHandler}>
+          <div className="navigation" onMouseLeave={hoverOutHandler}>
+            <div className="grw-navigation-wrap">
               <div className="grw-global-navigation">
                 { isMounted ? <GlobalNavigation></GlobalNavigation> : <GlobalNavigationSkelton></GlobalNavigationSkelton> }
               </div>
@@ -291,8 +291,6 @@ const Sidebar: FC<Props> = (props: Props) => {
                 ref={resizableContainer}
                 className="grw-contextual-navigation"
                 onMouseEnter={hoverOnResizableContainerHandler}
-                onMouseMove={draggableAreaMoveHandler}
-                onMouseUp={dragableAreaMouseUpHandler}
                 style={{ width: isCollapsed ? sidebarMinimizeWidth : currentProductNavWidth }}
               >
                 <div className="grw-contextual-navigation-child">
@@ -304,8 +302,8 @@ const Sidebar: FC<Props> = (props: Props) => {
             </div>
             <div className="grw-navigation-draggable">
               <div
-                className={`${!isDrawerMode ? 'resizable' : ''} grw-navigation-draggable-hitarea`}
-                onMouseDown={dragableAreaClickHandler}
+                className={`${isResizableByDrag ? 'resizable' : ''} grw-navigation-draggable-hitarea`}
+                onMouseDown={dragableAreaMouseDownHandler}
               >
                 <div className="grw-navigation-draggable-hitarea-child"></div>
               </div>