mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 01:01:38 +00:00
Add post toc
This commit is contained in:
@ -12,7 +12,7 @@ const Image = ({ alt, ...rest }: Props) => {
|
|||||||
className={classNames(
|
className={classNames(
|
||||||
'block mx-auto',
|
'block mx-auto',
|
||||||
'text-center text-gray-400',
|
'text-center text-gray-400',
|
||||||
'mt-2'
|
'my-2'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{alt}
|
{alt}
|
||||||
|
3
components/post/PostToc.module.css
Normal file
3
components/post/PostToc.module.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.head:hover:before {
|
||||||
|
content: unset !important;
|
||||||
|
}
|
64
components/post/PostToc.tsx
Normal file
64
components/post/PostToc.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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'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;
|
@ -1,44 +0,0 @@
|
|||||||
const app = `import { useForm } from 'react-hook-form';
|
|
||||||
|
|
||||||
type Pet = 'Cat' | 'Dog';
|
|
||||||
type FormData = {
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
favorite: Pet;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function App() {
|
|
||||||
const {
|
|
||||||
register,
|
|
||||||
handleSubmit,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm<FormData>();
|
|
||||||
const onSubmit = handleSubmit((data) => console.log(data));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<form onSubmit={onSubmit}>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="firstname">First name:</label>
|
|
||||||
<input type="text" id="firstname" {...register('firstName')} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label htmlFor="lastname">Last name:</label>
|
|
||||||
<input type="text" id="lastname" {...register('lastName')} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label htmlFor="favorite">Favorite pet:</label>
|
|
||||||
<select id="favorite" {...register('favorite')}>
|
|
||||||
<option value="cat">Cat</option>
|
|
||||||
<option value="dog">Dog</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button>Submit</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}`;
|
|
||||||
export default app;
|
|
@ -1,22 +0,0 @@
|
|||||||
const app = `import "./styles.css";
|
|
||||||
import Child from "./Child";
|
|
||||||
|
|
||||||
const testData = {
|
|
||||||
name: "xfy",
|
|
||||||
age: 18
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function App() {
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<h1>Hello CodeSandbox</h1>
|
|
||||||
<h2>Start editing to see some magic happen!</h2>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Child data={testData} name="name" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}`;
|
|
||||||
|
|
||||||
export default app;
|
|
@ -1,27 +0,0 @@
|
|||||||
const child = `import { useState } from "react";
|
|
||||||
|
|
||||||
type Props<T extends Record<string, unknown>> = {
|
|
||||||
name: keyof T;
|
|
||||||
data: T;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Child = <T extends Record<string, unknown>>({ name, data }: Props<T>) => {
|
|
||||||
const [showName, setShowName] = useState<T[keyof T]>();
|
|
||||||
const valid = () => {
|
|
||||||
console.log(data[name]);
|
|
||||||
setShowName(data[name]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div>{name}</div>
|
|
||||||
<button onClick={valid}>Show {name}</button>
|
|
||||||
|
|
||||||
<div>{JSON.stringify(showName)}</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Child;`;
|
|
||||||
|
|
||||||
export default child;
|
|
@ -118,7 +118,7 @@
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
#article .toc .is-active-link {
|
#article .toc .is-active-link {
|
||||||
@apply font-semibold transition-all;
|
@apply font-semibold;
|
||||||
}
|
}
|
||||||
|
|
||||||
#article p {
|
#article p {
|
||||||
|
Reference in New Issue
Block a user