mirror of
https://github.com/r-freeman/portfolio.git
synced 2025-04-21 23:54:37 +00:00
Add copy button to pre components
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m13s
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m13s
This commit is contained in:
parent
191705bf8b
commit
80ca065d12
10
components/icons/CheckIcon.tsx
Normal file
10
components/icons/CheckIcon.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import {Props} from '@/types'
|
||||||
|
|
||||||
|
export function CheckIcon(props: Props) {
|
||||||
|
return (
|
||||||
|
<svg fill="none" strokeWidth={1.5} stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
aria-hidden="true" {...props}>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
11
components/icons/CopyIcon.tsx
Normal file
11
components/icons/CopyIcon.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import {Props} from '@/types'
|
||||||
|
|
||||||
|
export function CopyIcon(props: Props) {
|
||||||
|
return (
|
||||||
|
<svg fill="none" strokeWidth={1.5} stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
aria-hidden="true" {...props}>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round"
|
||||||
|
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
@ -5,13 +5,11 @@ import {Prose} from '@/components/ui/Prose'
|
|||||||
import {Views} from '@/components/ui/Views'
|
import {Views} from '@/components/ui/Views'
|
||||||
import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
|
import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
|
||||||
import ArticleNav from '@/components/ui/ArticleNav'
|
import ArticleNav from '@/components/ui/ArticleNav'
|
||||||
import Comments from '@/components/ui/Comments'
|
import {Comments} from '@/components/ui/Comments'
|
||||||
import {getAllArticles} from '@/lib/getAllArticles'
|
import {getAllArticles} from '@/lib/getAllArticles'
|
||||||
import {getComments} from '@/lib/getComments'
|
import {getComments} from '@/lib/getComments'
|
||||||
import {format} from 'date-fns'
|
import {format} from 'date-fns'
|
||||||
|
|
||||||
import type {Comment} from '@/types'
|
|
||||||
|
|
||||||
type ArticleLayout = {
|
type ArticleLayout = {
|
||||||
title: string
|
title: string
|
||||||
date: string
|
date: string
|
||||||
|
29
components/ui/Code.tsx
Normal file
29
components/ui/Code.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, {ReactNode, useRef, useState} from 'react'
|
||||||
|
import {CopyIcon} from '@/components/icons/CopyIcon'
|
||||||
|
import {CheckIcon} from '@/components/icons/CheckIcon'
|
||||||
|
|
||||||
|
export function Code({children}: { children: ReactNode }) {
|
||||||
|
const [copied, setCopied] = useState<boolean>(false)
|
||||||
|
const preRef = useRef<HTMLPreElement>(null)
|
||||||
|
|
||||||
|
const handleCopy = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
await navigator.clipboard.writeText(preRef.current?.innerText ?? '')
|
||||||
|
setCopied(true)
|
||||||
|
setTimeout(() => setCopied(false), 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<pre className="relative" ref={preRef}>
|
||||||
|
<button className="absolute top-0 right-0 m-5" onClick={handleCopy} aria-label="Copy code">
|
||||||
|
{copied ? <CheckIcon className="size-5 text-indigo-500"/> :
|
||||||
|
<CopyIcon className="size-5 text-zinc-400 hover:text-zinc-50"/>}
|
||||||
|
</button>
|
||||||
|
<div className="mt-5 sm:mt-0 pb-5 overflow-auto ">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</pre>
|
||||||
|
)
|
||||||
|
}
|
@ -205,7 +205,7 @@ type CommentsProps = {
|
|||||||
comments?: any
|
comments?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Comments({slug, comments}: CommentsProps) {
|
export function Comments({slug, comments}: CommentsProps) {
|
||||||
return (
|
return (
|
||||||
<CommentFormProvider>
|
<CommentFormProvider>
|
||||||
<ReplyProvider>
|
<ReplyProvider>
|
||||||
|
@ -45,12 +45,7 @@ export const getCurrentlyPlaying = async () => {
|
|||||||
|
|
||||||
|
|
||||||
export const getRecentlyPlayed = async () => {
|
export const getRecentlyPlayed = async () => {
|
||||||
try {
|
|
||||||
const {access_token}: Response = await getAccessToken() as Response
|
const {access_token}: Response = await getAccessToken() as Response
|
||||||
} catch(e) {
|
|
||||||
console.error(e)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fetch(SPOTIFY_RECENTLY_PLAYED, {
|
return await fetch(SPOTIFY_RECENTLY_PLAYED, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import type {MDXComponents} from 'mdx/types'
|
import type {MDXComponents} from 'mdx/types'
|
||||||
|
import React from 'react'
|
||||||
|
import {Code} from '@/components/ui/Code'
|
||||||
import {Heading} from './components/ui/Heading'
|
import {Heading} from './components/ui/Heading'
|
||||||
|
|
||||||
// This file allows you to provide custom React components
|
// This file allows you to provide custom React components
|
||||||
@ -11,6 +13,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
|
|||||||
return {
|
return {
|
||||||
h2: ({children}) => <Heading as="h2">{children}</Heading>,
|
h2: ({children}) => <Heading as="h2">{children}</Heading>,
|
||||||
h3: ({children}) => <Heading as="h3">{children}</Heading>,
|
h3: ({children}) => <Heading as="h3">{children}</Heading>,
|
||||||
|
pre: ({children}) => <Code>{children}</Code>,
|
||||||
// Allows customizing built-in components, e.g. to add styling.
|
// Allows customizing built-in components, e.g. to add styling.
|
||||||
// h1: ({ children }) => <h1 style={{ fontSize: "100px" }}>{children}</h1>,
|
// h1: ({ children }) => <h1 style={{ fontSize: "100px" }}>{children}</h1>,
|
||||||
...components
|
...components
|
||||||
|
Loading…
x
Reference in New Issue
Block a user