Add new post

add new code sandbox component
This commit is contained in:
DefectingCat
2022-08-12 11:01:18 +08:00
parent b9bc6cdef6
commit 047fc0c775
16 changed files with 520 additions and 75 deletions

View File

@ -1,14 +1,11 @@
import classNames from 'classnames';
import useMounted from 'lib/hooks/useMounted';
import { useTheme } from 'next-themes';
import { useEffect, useState } from 'react';
import { FiMoon, FiSun } from 'react-icons/fi';
const DarkModeBtn = () => {
const [mounted, setMounted] = useState(false);
const { mounted } = useMounted();
const { systemTheme, theme, setTheme } = useTheme();
// When mounted on client, now we can show the UI
useEffect(() => setMounted(true), []);
const currentTheme = theme === 'system' ? systemTheme : theme;
if (!mounted)

View File

@ -0,0 +1,72 @@
import classNames from 'classnames';
import useInView from 'lib/hooks/useInView';
import { useTheme } from 'next-themes';
import { useCallback, useEffect, useRef, useState } from 'react';
import RUALoading from './loading/RUALoading';
const partten =
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
const commonClass = classNames(
'rounded-lg h-[500px] border-0',
'overflow-hidden w-full'
);
type Props = {
url: string;
};
const RUACodeSandbox = ({ url }: Props) => {
const isUrl = partten.test(url);
const { systemTheme, theme } = useTheme();
const currentTheme = theme === 'system' ? systemTheme : theme ?? 'light';
const { ref, inView } = useInView();
const sandUrl = new URL(url);
const embed = sandUrl.pathname.split('/')[2];
const [src, setSrc] = useState('');
useEffect(() => {
inView &&
setSrc(
`https://codesandbox.io/embed/${embed}?fontsize=14&hidenavigation=1&theme=${currentTheme}&view=preview`
);
}, [currentTheme, embed, inView]);
const [load, setLoad] = useState(false);
const handleLoad = useCallback(() => {
setLoad(true);
}, []);
if (!isUrl) return null;
return (
<>
<div className={classNames(commonClass, 'relative')}>
<div
className={classNames(
commonClass,
'absolute flex items-center justify-center',
load && 'hidden',
'transition-all z-10'
)}
>
<RUALoading />
</div>
<iframe
ref={ref}
src={src}
className={classNames(
commonClass,
!load && 'blur-sm',
'transition-all'
)}
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
onLoad={handleLoad}
></iframe>
</div>
</>
);
};
export default RUACodeSandbox;

View File

@ -1,3 +0,0 @@
.head:hover:before {
content: unset !important;
}

View File

@ -1,64 +0,0 @@
import { getHeadings } from 'lib/utils';
import Anchor from 'components/mdx/Anchor';
import styles from './PostTOC.module.css';
import classNames from 'classnames';
import { useCallback, useState } from 'react';
import { FiChevronDown } from 'react-icons/fi';
interface Props {
headings: ReturnType<typeof getHeadings>;
}
const PostTOC = ({ headings }: Props) => {
const [show, setShow] = useState(false);
const handleClick = useCallback(() => setShow((show) => !show), []);
return (
<>
<div
className={classNames(
'rounded-lg transition-all',
'duration-500 overflow-hidden',
'my-4'
)}
style={{
maxHeight: show ? (headings?.length ?? 0) * 50 + 70 : 70,
}}
>
<h2
className={classNames(
styles.head,
'bg-white !m-[unset] p-4',
'rounded-lg border border-gray-300',
'dark:bg-rua-gray-800 dark:border-rua-gray-600',
'select-none cursor-pointer',
'flex justify-between items-center',
'!text-2xl'
)}
onClick={handleClick}
>
<span>What&apos;s inside?</span>
<FiChevronDown
className={classNames(
show && 'rotate-180',
'transition-all duration-500'
)}
/>
</h2>
<ul className="pl-4 border-l-4 border-gray-300 toc">
{headings?.map((h) => (
<li key={h.link}>
<Anchor href={h.link} external={false}>
{h.text}
</Anchor>
</li>
))}
</ul>
</div>
</>
);
};
export default PostTOC;

View File

@ -1,9 +1,9 @@
import { useEffect, useState } from 'react';
import useMounted from 'lib/hooks/useMounted';
import { useEffect } from 'react';
import tocbot from 'tocbot';
const SlideToc = () => {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
const { mounted } = useMounted();
useEffect(() => {
// Waiting the right time.