sheets
This commit is contained in:
parent
c6522bb851
commit
f30dfc1f98
@ -9,7 +9,8 @@ import rehypeRaw from "rehype-raw";
|
||||
import rehypeHighlight from "rehype-highlight";
|
||||
import { notFound } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import CodeBlock from "$components/code-block";
|
||||
import CopyButton from "$components/copy-button";
|
||||
import { getText } from "@/app/lib/react";
|
||||
|
||||
type Params = {
|
||||
slug: string[]
|
||||
@ -75,7 +76,10 @@ export default function Content({ params }: Props) {
|
||||
},
|
||||
pre({ children, className }) {
|
||||
return (
|
||||
<CodeBlock className={className}>{children}</CodeBlock>
|
||||
<div className="relative">
|
||||
<CopyButton text={getText(children)} />
|
||||
<pre className={`${className || ""}`}>{children}</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}}
|
||||
|
@ -1,40 +0,0 @@
|
||||
"use client"
|
||||
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { ReactNode, useState } from "react"
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
const getText = (node: any) => {
|
||||
const props = node.props
|
||||
if (!props) {
|
||||
return node
|
||||
}
|
||||
const c = props.children
|
||||
return typeof c === "string" ? c : c.map(getText).join("")
|
||||
}
|
||||
|
||||
const CodeBlock = ({ className, children }: Props) => {
|
||||
const [visible, setVisible] = useState("invisible")
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<button
|
||||
className="absolute top-5 right-5"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(getText(children))
|
||||
setVisible("visible")
|
||||
setTimeout(() => setVisible("invisible"), 1000)
|
||||
}}
|
||||
>
|
||||
<span className={`${visible} absolute bottom-5 left-5`}><FontAwesomeIcon className="text-green-400" icon={faCheck} /></span>
|
||||
<FontAwesomeIcon icon={faCopy} />
|
||||
</button>
|
||||
<pre className={`${className || ""}`}>{children}</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CodeBlock;
|
27
src/app/components/copy-button.tsx
Normal file
27
src/app/components/copy-button.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
"use client"
|
||||
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { useState } from "react"
|
||||
|
||||
type Props = {
|
||||
text: string
|
||||
}
|
||||
|
||||
const CopyButton = ({ text }: Props) => {
|
||||
const [visible, setVisible] = useState("invisible")
|
||||
return (
|
||||
<button
|
||||
className="absolute top-5 right-5"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(text)
|
||||
setVisible("visible")
|
||||
setTimeout(() => setVisible("invisible"), 1000)
|
||||
}}
|
||||
>
|
||||
<span className={`${visible} absolute bottom-5 left-5`}><FontAwesomeIcon className="text-green-400" icon={faCheck} /></span>
|
||||
<FontAwesomeIcon className="" icon={faCopy} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default CopyButton;
|
@ -6,10 +6,10 @@ const Links = () =>
|
||||
<div className="grid w-full h-full place-content-center">
|
||||
<div className={"grid grid-cols-2 gap-4 place-content-center"}>
|
||||
<Link aria-label="GitHub" href={process.env.NEXT_PUBLIC_GITHUB_URL!} target="_blank">
|
||||
<FontAwesomeIcon icon={faGithub} />
|
||||
<FontAwesomeIcon className="svg-link" icon={faGithub} />
|
||||
</Link>
|
||||
<Link aria-label="GitLab" href={process.env.NEXT_PUBLIC_GITLAB_URL!} target="_blank">
|
||||
<FontAwesomeIcon icon={faGitlab} />
|
||||
<FontAwesomeIcon className="svg-link" icon={faGitlab} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ const mailto = `mailto:${email}`
|
||||
const Contact = () =>
|
||||
<div className="w-full h-full p-2 grid place-content-center">
|
||||
<div className="flex flex-row gap-4">
|
||||
<a aria-label={mailto} href={mailto}><FontAwesomeIcon icon={faEnvelope} /></a>
|
||||
<a aria-label={mailto} href={mailto}><FontAwesomeIcon className="svg-link" icon={faEnvelope} /></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -11,7 +11,11 @@ main {
|
||||
}
|
||||
|
||||
svg {
|
||||
@apply w-14 h-14 text-amber-100 hover:text-cyan-500
|
||||
@apply hover:text-cyan-500
|
||||
}
|
||||
|
||||
.svg-link {
|
||||
@apply w-14 h-14
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
10
src/app/lib/react.ts
Normal file
10
src/app/lib/react.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { ReactNode } from "react"
|
||||
|
||||
export const getText = (node: ReactNode | any) => {
|
||||
const props = node.props
|
||||
if (!props) {
|
||||
return node
|
||||
}
|
||||
const c = props.children
|
||||
return typeof c === "string" ? c : c.map(getText).join("")
|
||||
}
|
Loading…
Reference in New Issue
Block a user