From 4693cbba4f88a84dd1ec9d3324e0fa05123816ae Mon Sep 17 00:00:00 2001 From: hariombalhara Date: Wed, 16 Feb 2022 21:23:26 +0530 Subject: [PATCH] Feature: Instant Theme Change, without refresh [Booking Pages Only] (#1807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Avoid Theme Flicker. Render Server Side * Add back isReady implementation * Use shorter syntax for Tag * Listen to changes in pref-color-scheme and act * Uglify Theme Applier code * Resolve conflicts * Add comments * Appropriate function name * Move uglify-js to dependencies * Remove uglify-js * Fix commnt Co-authored-by: Peer Richelsen Co-authored-by: Omar López Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .vscode/extensions.json | 2 +- apps/web/lib/hooks/useTheme.tsx | 40 ++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d7192cb888..447e1ed7db 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,6 +7,6 @@ "bradlc.vscode-tailwindcss", // hinting / autocompletion for tailwind "ban.spellright", // Spell check for docs "stripe.vscode-stripe", // stripe VSCode extension - "Prisma.prisma" // syntax|format|completion for prisma + "Prisma.prisma" // syntax|format|completion for prisma ] } diff --git a/apps/web/lib/hooks/useTheme.tsx b/apps/web/lib/hooks/useTheme.tsx index 2b9ff7e59f..2fab3f02b0 100644 --- a/apps/web/lib/hooks/useTheme.tsx +++ b/apps/web/lib/hooks/useTheme.tsx @@ -3,28 +3,42 @@ import { useEffect, useState } from "react"; import { Maybe } from "@trpc/server"; +// This method is stringified and executed only on client. So, +// - Pass all the params explicitly to this method. Don't use closure +function applyThemeAndAddListener(theme: string) { + const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); + const applyTheme = function (theme: string, darkMatch: boolean) { + if (!theme) { + if (darkMatch) { + document.documentElement.classList.add("dark"); + } else { + document.documentElement.classList.remove("dark"); + } + } else { + document.documentElement.classList.add(theme); + } + }; + mediaQueryList.onchange = function (e) { + applyTheme(theme, e.matches); + }; + applyTheme(theme, mediaQueryList.matches); +} + // makes sure the ui doesn't flash export default function useTheme(theme?: Maybe) { const [isReady, setIsReady] = useState(false); + useEffect(() => { + // TODO: isReady doesn't seem required now. This is also impacting PSI Score for pages which are using isReady. setIsReady(true); }, []); + function Theme() { - const themeString = theme ? `"${theme}"` : null; + const code = applyThemeAndAddListener.toString(); + const themeStr = theme ? `"${theme}"` : null; return ( - + ); }