mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-06-05 19:15:30 -04:00
fix flash of white in dark mode
This commit is contained in:
+11
-15
@@ -1,22 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import { forwardRef, useState, useEffect } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { ClipboardIcon, CheckIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const CopyButton = (
|
||||
{
|
||||
source,
|
||||
timeout = 2000,
|
||||
className,
|
||||
...rest
|
||||
}: React.ComponentProps<"button"> & {
|
||||
source: string;
|
||||
timeout?: number;
|
||||
},
|
||||
ref: React.Ref<React.ComponentRef<"button">>
|
||||
) => {
|
||||
const CopyButton = ({
|
||||
source,
|
||||
timeout = 2000,
|
||||
className,
|
||||
...rest
|
||||
}: React.ComponentProps<"button"> & {
|
||||
source: string;
|
||||
timeout?: number;
|
||||
}) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy: React.MouseEventHandler<React.ComponentRef<"button">> = (e) => {
|
||||
@@ -48,7 +45,6 @@ const CopyButton = (
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
onClick={handleCopy}
|
||||
disabled={copied}
|
||||
className={cn("cursor-pointer disabled:cursor-default", className)}
|
||||
@@ -60,4 +56,4 @@ const CopyButton = (
|
||||
);
|
||||
};
|
||||
|
||||
export default forwardRef(CopyButton);
|
||||
export default CopyButton;
|
||||
|
||||
@@ -19,7 +19,7 @@ const Header = ({ className, ...rest }: React.ComponentProps<"header">) => {
|
||||
<Image
|
||||
src={avatarImg}
|
||||
alt={`Photo of ${siteConfig.name}`}
|
||||
className="border-ring/80 size-[64px] rounded-full border-2 md:size-[48px] md:border-1"
|
||||
className="border-ring/40 size-[64px] rounded-full border-2 md:size-[48px] md:border-1"
|
||||
width={64}
|
||||
height={64}
|
||||
quality={50}
|
||||
@@ -30,7 +30,7 @@ const Header = ({ className, ...rest }: React.ComponentProps<"header">) => {
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<Menu className="w-full max-w-64 sm:max-w-96 md:ml-0 md:max-w-none" />
|
||||
<Menu className="w-full max-w-64 sm:max-w-96 md:max-w-none" />
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { isValidElement } from "react";
|
||||
import Link from "@/components/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -9,15 +8,21 @@ const MenuItem = ({
|
||||
current,
|
||||
className,
|
||||
...rest
|
||||
}: Omit<React.ComponentProps<typeof Link>, "href"> & {
|
||||
}: React.ComponentProps<"div"> & {
|
||||
text?: string;
|
||||
href?: `/${string}`;
|
||||
icon?: React.ReactNode;
|
||||
icon: React.ReactNode;
|
||||
current?: boolean;
|
||||
}) => {
|
||||
const item = (
|
||||
<div className="[&_svg]:stroke-foreground/85 inline-flex items-center [&_svg]:size-7 [&_svg]:md:size-5">
|
||||
{isValidElement(icon) && icon}
|
||||
<div
|
||||
className={cn(
|
||||
"[&_svg]:stroke-foreground/85 inline-flex items-center [&_svg]:size-7 [&_svg]:md:size-5",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{icon}
|
||||
{text && <span className="ml-3 text-sm leading-none font-medium tracking-wide max-md:sr-only">{text}</span>}
|
||||
</div>
|
||||
);
|
||||
@@ -30,11 +35,7 @@ const MenuItem = ({
|
||||
href={href}
|
||||
aria-label={text}
|
||||
data-current={current || undefined}
|
||||
className={cn(
|
||||
"text-foreground/85 hover:border-ring data-current:border-primary/40! inline-flex items-center border-b-3 border-b-transparent hover:no-underline",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
className="text-foreground/85 hover:border-ring/80 data-current:border-primary/60! inline-flex items-center border-b-3 border-b-transparent hover:no-underline"
|
||||
>
|
||||
{item}
|
||||
</Link>
|
||||
|
||||
@@ -44,10 +44,7 @@ const Menu = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
const isCurrent = item.href?.split("/")[1] === segment;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="inline-block border-t-3 border-t-transparent last:-mr-2.5 max-sm:first:hidden [&_a,&_button]:p-2.5"
|
||||
key={index}
|
||||
>
|
||||
<div className="mt-[3px] inline-block last:-mr-2.5 max-sm:first:hidden **:[a,button]:p-2.5" key={index}>
|
||||
<MenuItem {...item} current={isCurrent} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -51,16 +51,3 @@ export const ThemeProvider = ({ children }: React.PropsWithChildren) => {
|
||||
|
||||
return <ThemeContext.Provider value={providerValues}>{children}</ThemeContext.Provider>;
|
||||
};
|
||||
|
||||
// loaded in <head> by layout.tsx to avoid blinding flash of unstyled content (FOUC). irrelevant after the first render
|
||||
// since the theme provider above takes over.
|
||||
// unminified JS: https://gist.github.com/jakejarvis/79b0ec8506bc843023546d0d29861bf0
|
||||
export const ThemeScript = () => (
|
||||
<script
|
||||
id="restore-theme"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
"(()=>{try{const e=document.documentElement,t='undefined'!=typeof Storage?window.localStorage.getItem('theme'):null,a=(t&&'dark'===t)??window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';e.dataset.theme=a,e.style.colorScheme=a}catch(e){}})()",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// loaded in <head> by layout.tsx to avoid blinding flash of unstyled content (FOUC). irrelevant after the first render
|
||||
// when <ThemeProvider /> takes over.
|
||||
// unminified JS: https://gist.github.com/jakejarvis/79b0ec8506bc843023546d0d29861bf0
|
||||
export const ThemeScript = () => (
|
||||
<script
|
||||
id="restore-theme"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
"(()=>{try{const e=document.documentElement,t='undefined'!=typeof Storage?window.localStorage.getItem('theme'):null,a=(t&&'dark'===t)??window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';e.dataset.theme=a,e.style.colorScheme=a}catch(e){}})()",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -13,7 +13,7 @@ const ThemeToggle = ({ className, ...rest }: React.ComponentProps<"button">) =>
|
||||
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
|
||||
aria-label="Toggle theme"
|
||||
className={cn(
|
||||
"hover:*:stroke-warning block cursor-pointer bg-transparent not-dark:[&_.lucide-moon]:hidden dark:[&_.lucide-sun]:hidden",
|
||||
"hover:[&_svg]:stroke-warning block cursor-pointer bg-transparent not-dark:[&_.lucide-moon]:hidden dark:[&_.lucide-sun]:hidden",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
|
||||
Reference in New Issue
Block a user