mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-15 08:41:37 +00:00
fix sandpack theme handle
This commit is contained in:
@ -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) {}
|
||||||
|
@ -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 = () => {
|
||||||
|
@ -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
9
lib/consts.ts
Normal 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,
|
||||||
|
};
|
Reference in New Issue
Block a user