Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for configuration option for color mode on printing #1144

Closed
lachlanjc opened this issue Aug 20, 2020 · 2 comments · Fixed by #1267
Closed

Request for configuration option for color mode on printing #1144

lachlanjc opened this issue Aug 20, 2020 · 2 comments · Fixed by #1267

Comments

@lachlanjc
Copy link
Member

Is your feature request related to a problem? Please describe.
When printing out a webpage as a PDF or on paper, there’s no way to have Theme UI automatically apply a certain color mode.

Describe the solution you'd like
Just like initialColorModeName, I’d like there to be a new configuration option printColorModeName, which applies that color mode inside @media print.

Describe alternatives you've considered
Haven’t considered alternatives, this seems like the easiest approach.

Additional context
It’s difficult right now to add great printing styles to Theme UI sites, especially when they’re in dark mode. You end up with needing global CSS with lots of !important to make everything the right colors.

@hasparus
Copy link
Member

I had a similar problem. I worked around it with useEffect (below).

printColorModeName and @media print would be a pretty sweet solution!


/** @jsx jsx */
import { jsx, useColorMode } from "theme-ui";
import { useEffect, useState, useRef } from "react";

import { ColorModes, fontSize } from "../gatsby-plugin-theme-ui";
import { Button } from "./Button";

function useWindowPrint(options: {
  onBeforePrint: () => void;
  onAfterPrint: () => void;
}) {
  type State = "Ready" | "Printing" | "Printed";
  const [state, setState] = useState<State>("Ready");

  const onAfterCurrentPrint = useRef<() => void>(options.onAfterPrint);
  useEffect(() => {
    switch (state) {
      case "Ready":
        break;
      case "Printing":
        window.print();
        break;
      case "Printed":
        if (onAfterCurrentPrint.current) {
          onAfterCurrentPrint.current();
        }
        setState("Ready");
        break;
      default: {
        const _: never = state;
        throw new Error("switch is not exhaustive");
      }
    }
  }, [state, setState]);

  useEffect(() => {
    const handleAfterPrint = () => {
      setState("Printed");
    };
    window.addEventListener("afterprint", handleAfterPrint);

    return () => {
      window.removeEventListener("afterprint", handleAfterPrint);
    };
  }, []);

  return function print() {
    options.onBeforePrint();
    onAfterCurrentPrint.current = options.onAfterPrint;
    setState("Printing");
  };
}

export function PrintItButton() {
  const [colorMode, setColorMode] = useColorMode();
  const print = useWindowPrint({
    onBeforePrint: () => setColorMode("light"),
    onAfterPrint: () => setColorMode(colorMode!),
  });

  return (
    <Button onClick={print}>
      Print it 🖨
    </Button>
  );
}

@lachlanjc
Copy link
Member Author

Wow, very nice. I was investigating implementation & I think we could do this with pure CSS & custom properties which would be awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants