Explorar o código

Merge pull request #10505 from growilabs/fix/printing-styles

fix: Printing styles
mergify[bot] hai 4 meses
pai
achega
368e2730b5

+ 3 - 0
apps/app/src/client/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -19,6 +19,7 @@ import Sticky from 'react-stickynode';
 import { DropdownItem, UncontrolledTooltip, Tooltip } from 'reactstrap';
 
 import { exportAsMarkdown, updateContentWidth, syncLatestRevisionBody } from '~/client/services/page-operation';
+import { usePrintMode } from '~/client/services/use-print-mode';
 import { toastSuccess, toastError, toastWarning } from '~/client/util/toastr';
 import { GroundGlassBar } from '~/components/Navbar/GroundGlassBar';
 import { usePageBulkExportSelectModal } from '~/features/page-bulk-export/client/stores/modal';
@@ -252,6 +253,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
   const { t } = useTranslation();
 
   const router = useRouter();
+  const isPrinting = usePrintMode();
 
   const { data: shareLinkId } = useShareLinkId();
   const { trigger: mutateCurrentPage } = useSWRMUTxCurrentPage();
@@ -385,6 +387,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
 
       <Sticky
         className="z-1"
+        enabled={!isPrinting}
         onStateChange={status => setStickyActive(status.status === Sticky.STATUS_FIXED)}
         innerActiveClass="w-100 end-0"
       >

+ 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} mb-4`} 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;
 

+ 0 - 3
apps/app/src/client/components/PageSideContents/PageSideContents.module.scss

@@ -1,3 +0,0 @@
-/* stylelint-disable-next-line block-no-empty */
-.grw-page-accessories-controls :global {
-}

+ 1 - 3
apps/app/src/client/components/PageSideContents/PageSideContents.tsx

@@ -19,8 +19,6 @@ import TableOfContents from '../TableOfContents';
 
 import { PageAccessoriesControl } from './PageAccessoriesControl';
 
-import styles from './PageSideContents.module.scss';
-
 
 const { isTopPage, isUsersHomepage, isTrashPage } = pagePathUtils;
 
@@ -117,7 +115,7 @@ export const PageSideContents = (props: PageSideContentsProps): JSX.Element => {
         </div>
       )}
 
-      <div className={`${styles['grw-page-accessories-controls']} d-flex flex-column gap-2`}>
+      <div className=" d-flex flex-column gap-2">
         {/* Page list */}
         {!isSharedUser && (
           <div className="d-flex" data-testid="pageListButton">

+ 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;
+};

+ 4 - 6
apps/app/src/components/Common/PagePathNavTitle/PagePathNavTitle.tsx

@@ -41,17 +41,15 @@ export const PagePathNavTitle = (
     setClient(true);
   }, []);
 
+  const className = `${moduleClass} mb-4`;
+
   return isClient ? (
     <PagePathNavSticky
       {...props}
-      className={moduleClass}
+      className={className}
       latterLinkClassName="fs-2"
     />
   ) : (
-    <PagePathNav
-      {...props}
-      className={moduleClass}
-      latterLinkClassName="fs-2"
-    />
+    <PagePathNav {...props} className={className} latterLinkClassName="fs-2" />
   );
 };

+ 2 - 3
apps/app/src/components/PageView/PageContentFooter.tsx

@@ -21,13 +21,12 @@ export const PageContentFooter = (
   const { creator, lastUpdateUser, createdAt, updatedAt } = page;
 
   if (page.isEmpty) {
+    // biome-ignore lint/complexity/noUselessFragments: ignore
     return <></>;
   }
 
   return (
-    <div
-      className={`${styles['page-content-footer']} my-4 pt-4 d-edit-none d-print-none}`}
-    >
+    <div className={`${styles['page-content-footer']} my-4 pt-4 d-edit-none`}>
       <div className="page-meta">
         <AuthorInfo
           user={creator}

+ 6 - 2
apps/app/src/components/PageView/PageViewLayout.tsx

@@ -1,5 +1,7 @@
 import type { JSX, ReactNode } from 'react';
 
+import { usePrintMode } from '~/client/services/use-print-mode';
+
 import styles from './PageViewLayout.module.scss';
 
 const pageViewLayoutClass = styles['page-view-layout'] ?? '';
@@ -24,6 +26,8 @@ export const PageViewLayout = (props: Props): JSX.Element => {
     expandContentWidth,
   } = props;
 
+  const isPrinting = usePrintMode();
+
   const fluidLayoutClass = expandContentWidth ? _fluidLayoutClass : '';
 
   return (
@@ -33,13 +37,13 @@ export const PageViewLayout = (props: Props): JSX.Element => {
       >
         <div className="container-lg wide-gutter-x-lg grw-container-convertible flex-expand-vert">
           {headerContents != null && headerContents}
-          {sideContents != null ? (
+          {!isPrinting && sideContents != null ? (
             <div className="flex-expand-horiz gap-3 z-0">
               <div className="flex-expand-vert flex-basis-0 mw-0">
                 {children}
               </div>
               <div
-                className="grw-side-contents-container col-lg-3  d-edit-none d-print-none"
+                className="grw-side-contents-container col-lg-3 d-edit-none"
                 data-vrt-blackout-side-contents
               >
                 <div className="grw-side-contents-sticky-container">

+ 5 - 0
apps/app/src/styles/_layout.scss

@@ -89,6 +89,11 @@ body {
     padding: 30px;
   }
 
+  // Avoid the issue where the footer element overlaps the main content
+  .dynamic-layout-root {
+    display: block !important;
+  }
+
   a::after {
     display: none !important;
   }