fix sandpack theme handle

This commit is contained in:
DefectingCat
2023-11-10 10:54:47 +08:00
parent 6f6f24a050
commit 072498779b
4 changed files with 36 additions and 14 deletions

View File

@ -1,23 +1,18 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { MEDIA, THEME_MAP } from 'lib/consts';
import useMounted from 'lib/hooks/use-mounted'; import useMounted from 'lib/hooks/use-mounted';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { memo, useCallback, useEffect } from 'react'; import { memo, useCallback, useEffect } from 'react';
import { FiMoon, FiSun } from 'react-icons/fi'; import { FiMoon, FiSun } from 'react-icons/fi';
const MEDIA = '(prefers-color-scheme: dark)';
const DarkModeBtn = () => { const DarkModeBtn = () => {
const { mounted } = useMounted(); const { mounted } = useMounted();
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
const handleTheme = (type: 'latte' | 'mocha') => () => { const handleTheme = (type: 'latte' | 'mocha') => () => {
const media = window.matchMedia(MEDIA); const media = window.matchMedia(MEDIA);
const map = {
light: 'latte',
dark: 'mocha',
};
const system = media.matches ? 'dark' : 'light'; const system = media.matches ? 'dark' : 'light';
setTheme(type); setTheme(type);
if (map[system] === type) { if (THEME_MAP[system] === type) {
try { try {
window.localStorage.removeItem('rua-theme'); window.localStorage.removeItem('rua-theme');
} catch (err) {} } catch (err) {}

View File

@ -5,6 +5,7 @@ import useInView from 'lib/hooks/use-in-view';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { memo, useEffect, useState } from 'react'; import { memo, useEffect, useState } from 'react';
import RUALoading from './loading/rua-loading'; import RUALoading from './loading/rua-loading';
import { THEME_CATPUCCIN_MAP, THEME_MAP } from 'lib/consts';
const pattern = const pattern =
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/; /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/;
@ -19,8 +20,7 @@ type Props = {
const RUACodeSandbox = ({ url }: Props) => { const RUACodeSandbox = ({ url }: Props) => {
const isUrl = pattern.test(url); const isUrl = pattern.test(url);
const { systemTheme, theme } = useTheme(); const { theme } = useTheme();
const currentTheme = theme === 'system' ? systemTheme : theme ?? 'light';
const { ref, inView } = useInView(); const { ref, inView } = useInView();
const embed = new URL(url).pathname.split('/')[2]; const embed = new URL(url).pathname.split('/')[2];
@ -28,9 +28,13 @@ const RUACodeSandbox = ({ url }: Props) => {
useEffect(() => { useEffect(() => {
inView && inView &&
setSrc( setSrc(
`https://codesandbox.io/embed/${embed}?fontsize=14&hidenavigation=1&theme=${currentTheme}&view=preview`, `https://codesandbox.io/embed/${embed}?fontsize=14&hidenavigation=1&theme=${
THEME_CATPUCCIN_MAP[
(theme ?? 'latte') as keyof typeof THEME_CATPUCCIN_MAP
]
}&view=preview`,
); );
}, [currentTheme, embed, inView]); }, [embed, inView, theme]);
const [load, setLoad] = useState(false); const [load, setLoad] = useState(false);
const handleLoad = () => { const handleLoad = () => {

View File

@ -1,21 +1,35 @@
'use client'; 'use client';
import { Sandpack, SandpackProps } from '@codesandbox/sandpack-react'; import { Sandpack, SandpackProps } from '@codesandbox/sandpack-react';
import { THEME_CATPUCCIN_MAP } from 'lib/consts';
import useMounted from 'lib/hooks/use-mounted';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { memo } from 'react'; import { memo } from 'react';
interface Props extends SandpackProps {} interface Props extends SandpackProps {}
const RUASandpack = ({ ...rest }: Props) => { const RUASandpack = ({ ...rest }: Props) => {
const { systemTheme, theme } = useTheme(); const { mounted } = useMounted();
const currentTheme = theme === 'system' ? systemTheme : theme; const { theme } = useTheme();
if (!mounted) {
return (
<div className="my-2 min-h-[402px]">
<Sandpack {...rest} />
</div>
);
}
return ( return (
<> <>
<div className="my-2 min-h-[402px]"> <div className="my-2 min-h-[402px]">
<Sandpack <Sandpack
{...rest} {...rest}
theme={currentTheme === 'dark' ? 'dark' : 'light'} theme={
THEME_CATPUCCIN_MAP[
(theme ?? 'latte') as keyof typeof THEME_CATPUCCIN_MAP
]
}
/> />
</div> </div>
</> </>

9
lib/consts.ts Normal file
View File

@ -0,0 +1,9 @@
export const MEDIA = '(prefers-color-scheme: dark)';
export const THEME_CATPUCCIN_MAP = {
latte: 'light' as const,
mocha: 'dark' as const,
};
export const THEME_MAP = {
light: 'latte' as const,
dark: 'mocha' as const,
};