mirror of
https://github.com/r-freeman/portfolio.git
synced 2025-04-19 12:24:46 +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 {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
|
||||
import ArticleNav from '@/components/ui/ArticleNav'
|
||||
import Comments from '@/components/ui/Comments'
|
||||
import {Comments} from '@/components/ui/Comments'
|
||||
import {getAllArticles} from '@/lib/getAllArticles'
|
||||
import {getComments} from '@/lib/getComments'
|
||||
import {format} from 'date-fns'
|
||||
|
||||
import type {Comment} from '@/types'
|
||||
|
||||
type ArticleLayout = {
|
||||
title: 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
|
||||
}
|
||||
|
||||
export default function Comments({slug, comments}: CommentsProps) {
|
||||
export function Comments({slug, comments}: CommentsProps) {
|
||||
return (
|
||||
<CommentFormProvider>
|
||||
<ReplyProvider>
|
||||
|
@ -45,12 +45,7 @@ export const getCurrentlyPlaying = async () => {
|
||||
|
||||
|
||||
export const getRecentlyPlayed = async () => {
|
||||
try {
|
||||
const {access_token}: Response = await getAccessToken() as Response
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
return null
|
||||
}
|
||||
const {access_token}: Response = await getAccessToken() as Response
|
||||
|
||||
return await fetch(SPOTIFY_RECENTLY_PLAYED, {
|
||||
headers: {
|
||||
|
@ -1,4 +1,6 @@
|
||||
import type {MDXComponents} from 'mdx/types'
|
||||
import React from 'react'
|
||||
import {Code} from '@/components/ui/Code'
|
||||
import {Heading} from './components/ui/Heading'
|
||||
|
||||
// This file allows you to provide custom React components
|
||||
@ -11,6 +13,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
|
||||
return {
|
||||
h2: ({children}) => <Heading as="h2">{children}</Heading>,
|
||||
h3: ({children}) => <Heading as="h3">{children}</Heading>,
|
||||
pre: ({children}) => <Code>{children}</Code>,
|
||||
// Allows customizing built-in components, e.g. to add styling.
|
||||
// h1: ({ children }) => <h1 style={{ fontSize: "100px" }}>{children}</h1>,
|
||||
...components
|
||||
|
Loading…
Reference in New Issue
Block a user