Copy button for code blocks (#2248)

* feat: Copy button for code blocks

Just a basic copy button in the code blocks so users can copy commands more easily. Inspired by Github's copy button.

* feat: Add Info for Image Cycler

A small little tooltip type text letting the user know that the image on the main page can be cycled through when hovered on.

* fix: Spelling mistake lol

* fix: Make button bigger so it looks centered

Make it look centered on one line big code blocks.

* fix: Tailwind Linting
This commit is contained in:
Arnab Chakraborty 2024-03-27 00:39:02 -04:00 committed by GitHub
parent 83332dc94e
commit f190dd3ff0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 80 additions and 29 deletions

View file

@ -6,6 +6,7 @@ import { getLatestRelease, getReleaseFrontmatter, githubFetch } from './api/gith
import { Background } from './Background';
import { Downloads } from './Downloads';
import { NewBanner } from './NewBanner';
import { ArrowUp } from '@phosphor-icons/react/dist/ssr';
export const metadata = {
title: 'Spacedrive — A file manager from the future.',
@ -77,34 +78,38 @@ export default async function Page() {
src="/images/app/gradient.webp"
/>
<div className="relative m-auto mt-10 flex w-full max-w-7xl overflow-hidden rounded-lg transition-transform duration-700 ease-in-out hover:-translate-y-4 hover:scale-[1.02] md:mt-0">
<div className="z-30 flex w-full rounded-lg border-t border-app-line/50 backdrop-blur">
<CyclingImage
loading="eager"
width={1278}
height={626}
alt="spacedrive app"
className="rounded-lg"
images={[
'/images/app/1.webp',
'/images/app/2.webp',
'/images/app/3.webp',
'/images/app/4.webp',
'/images/app/5.webp',
'/images/app/10.webp',
'/images/app/6.webp',
'/images/app/7.webp',
'/images/app/8.webp',
'/images/app/9.webp'
]}
/>
<Image
loading="eager"
className="pointer-events-none absolute opacity-100 transition-opacity duration-1000 ease-in-out hover:opacity-0 md:w-auto"
width={2278}
height={626}
alt="l"
src="/images/app/gradient-overlay.png"
/>
<div className='flex flex-col items-center justify-center'>
<div className="z-30 flex w-full rounded-lg border-t border-app-line/50 backdrop-blur">
<CyclingImage
loading="eager"
width={1278}
height={626}
alt="spacedrive app"
className="rounded-lg"
images={[
'/images/app/1.webp',
'/images/app/2.webp',
'/images/app/3.webp',
'/images/app/4.webp',
'/images/app/5.webp',
'/images/app/10.webp',
'/images/app/6.webp',
'/images/app/7.webp',
'/images/app/8.webp',
'/images/app/9.webp'
]}
/>
<Image
loading="eager"
className="pointer-events-none absolute opacity-100 transition-opacity duration-1000 ease-in-out hover:opacity-0 md:w-auto"
width={2278}
height={626}
alt="l"
src="/images/app/gradient-overlay.png"
/>
</div>
<ArrowUp className='invisible size-7 pt-2 text-white/40 md:visible' />
<p className='invisible pt-2 text-xs text-white/40 md:visible'>Hover on the image above to see how the app works!</p>
</div>
</div>
</div>

View file

@ -0,0 +1,37 @@
"use client";
import { Check } from '@phosphor-icons/react';
import { Copy } from '@phosphor-icons/react/dist/ssr';
import { useState, useRef, FC } from 'react'
const Pre: FC<{ children: React.ReactNode }> = ({ children }) => {
const textInput = useRef<HTMLDivElement | null>(null)
const [copied, setCopied] = useState(false)
const onCopy = () => {
setCopied(true)
navigator.clipboard.writeText(textInput.current!.textContent ?? '')
setTimeout(() => {
setCopied(false)
}, 2000)
}
return (
<div ref={textInput} className="relative">
<button
aria-label="Copy code"
type="button"
className="absolute right-2 top-2 z-10 rounded-md bg-app-box p-3 text-white/60 transition-colors duration-200 ease-in-out hover:bg-app-darkBox"
onClick={onCopy}
>
{copied ?
<Check className="my-0 size-5 text-green-400/60" />
:
<Copy className="my-0 size-5 text-white" />
}
</button>
<pre className='language-container'>{children}</pre>
</div >
)
}
export default Pre

View file

@ -4,6 +4,7 @@ import { env } from '~/env';
import Notice from './Notice';
import Video from './Video';
import Pre from './Pre';
const Image = (props: ImageProps) => (
<NextImage
@ -15,8 +16,9 @@ const Image = (props: ImageProps) => (
export const BlogMDXComponents = {
img: Image, // we remap 'img' to 'Image'
pre: Pre,
Image,
Video
} as MDXComponents;
export const DocMDXComponents = { img: Image, Image, Notice, Video } as MDXComponents;
export const DocMDXComponents = { img: Image, Image, Notice, Video, pre: Pre } as MDXComponents;

View file

@ -74,6 +74,13 @@ pre[class*='language-'] {
border-radius: 0.3em;
}
pre.language-container {
padding: 1.1em;
margin: 0.5em 0;
overflow: auto;
border-radius: 0.3em;
}
/* Inline code */
:not(pre) > code[class*='language-'] {
padding: 0.2em 0.3em;