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

add usePrintMode hook and integrate it into PagePathNavSticky component

Yuki Takei 4 месяцев назад
Родитель
Сommit
3df78d67b2

+ 0 - 8
apps/app/src/client/components/PagePathNavSticky/PagePathNavSticky.module.scss

@@ -13,11 +13,3 @@
     }
   }
 }
-
-@media print {
-  .grw-page-path-nav-sticky :global {
-    .sticky-inner-wrapper {
-      position: static !important;
-    }
-  }
-}

+ 4 - 1
apps/app/src/client/components/PagePathNavSticky/PagePathNavSticky.tsx

@@ -6,6 +6,7 @@ import { DevidedPagePath } from '@growi/core/dist/models';
 import { pagePathUtils } from '@growi/core/dist/utils';
 import Sticky from 'react-stickynode';
 
+import { usePrintMode } from '~/client/services/use-print-mode';
 import LinkedPagePath from '~/models/linked-page-path';
 import {
   usePageControlsX, useCurrentProductNavWidth, useSidebarMode,
@@ -27,6 +28,8 @@ const { isTrashPage } = pagePathUtils;
 export const PagePathNavSticky = (props: PagePathNavLayoutProps): JSX.Element => {
   const { pagePath } = props;
 
+  const isPrinting = usePrintMode();
+
   const { data: pageControlsX } = usePageControlsX();
   const { data: sidebarWidth } = useCurrentProductNavWidth();
   const { data: sidebarMode } = useSidebarMode();
@@ -82,7 +85,7 @@ export const PagePathNavSticky = (props: PagePathNavLayoutProps): JSX.Element =>
     // Controlling pointer-events
     //  1. disable pointer-events with 'pe-none'
     <div ref={pagePathNavRef}>
-      <Sticky className={moduleClass} innerClass="pe-none" innerActiveClass="active mt-1">
+      <Sticky className={moduleClass} enabled={!isPrinting} innerClass="pe-none" innerActiveClass="active mt-1">
         {({ status }) => {
           const isParentsCollapsed = status === Sticky.STATUS_FIXED;
 

+ 28 - 0
apps/app/src/client/services/use-print-mode.ts

@@ -0,0 +1,28 @@
+import { useEffect, useState } from 'react';
+
+import { flushSync } from 'react-dom';
+
+export const usePrintMode = (): boolean => {
+  const [isPrinting, setIsPrinting] = useState(false);
+
+  useEffect(() => {
+    // force re-render on beforeprint
+    const handleBeforePrint = () => flushSync(() => {
+      setIsPrinting(true);
+    });
+
+    const handleAfterPrint = () => {
+      setIsPrinting(false);
+    };
+
+    window.addEventListener('beforeprint', handleBeforePrint);
+    window.addEventListener('afterprint', handleAfterPrint);
+
+    return () => {
+      window.removeEventListener('beforeprint', handleBeforePrint);
+      window.removeEventListener('afterprint', handleAfterPrint);
+    };
+  }, []);
+
+  return isPrinting;
+};