Skip to content

Commit

Permalink
refactor(example/site): prism renderer, copy button (pmndrs#503)
Browse files Browse the repository at this point in the history
* refactor(example): prism renderer, copy button

added a more maintained prism renderer instead
of react-prism and also a copy button in case
someone wishes to clone the code instead of
enabling pointer events on everything

* fix(code-preview): wait on mount

wait for the element to mount before showing the preview, fixes
pmndrs#503 (comment)

* fix(code-preview): replace with `pre` tag

renderer depends on a pre tag, changed style and tags to match the same
  • Loading branch information
barelyhuman authored Jul 22, 2021
1 parent b941d44 commit d2f5af3
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 40 deletions.
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
"@testing-library/user-event": "^12.0.11",
"drei": "^0.0.72",
"postprocessing": "^6.16.0",
"prism-react-renderer": "^1.2.1",
"prismjs": "1.23.0",
"raw.macro": "^0.4.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-postprocessing": "^1.1.4",
"react-prism": "^4.3.2",
"react-scripts": "3.4.3",
"react-spring": "^8.0.27",
"react-three-fiber": "^4.2.20",
Expand Down
4 changes: 2 additions & 2 deletions examples/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Canvas, useFrame, useThree } from 'react-three-fiber'
import { Plane, useAspect, useTextureLoader } from 'drei'
import { EffectComposer, DepthOfField, Vignette } from 'react-postprocessing'
import create from 'zustand'
import PrismCode from 'react-prism'
import CodePreview from './components/CodePreview'
import 'prismjs'
import 'prismjs/components/prism-jsx.min'
import 'prismjs/themes/prism-okaidia.css'
Expand Down Expand Up @@ -110,7 +110,7 @@ export default function App() {
<div className="main">
<div className="code">
<div className="code-container">
<PrismCode className="language-jsx" children={code} />
<CodePreview code={code} />
<Counter />
</div>
</div>
Expand Down
28 changes: 28 additions & 0 deletions examples/src/components/CodePreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import Highlight, { defaultProps } from 'prism-react-renderer'
import { CopyButton } from './CopyButton'
import 'prismjs'
import 'prismjs/components/prism-jsx.min'
import 'prismjs/themes/prism-okaidia.css'

function CodePreview({ code, ...props }) {
return (
<Highlight {...defaultProps} className="language-jsx" code={code} language="jsx" theme={undefined}>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
// define how each line is to be rendered in the code block,
// position is set to relative so the copy button can align to bottom right
<pre className={className} style={{ ...style, position: 'relative' }}>
{tokens.map((line, i) => (
<div {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span {...getTokenProps({ token, key })} />
))}
</div>
))}
<CopyButton code={code} />
</pre>
)}
</Highlight>
)
}
export default CodePreview
43 changes: 43 additions & 0 deletions examples/src/components/CopyButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { useState } from 'react'
import { copyToClipboard } from '../utils/copy-to-clipboard'

/*
Isolated logic for the entire copy functionality instead
of a separate button component and with the added utility
*/
export function CopyButton({ code, ...props }) {
const [isCopied, setIsCopied] = useState(false)

const handleCopy = () => {
copyToClipboard(code)
setIsCopied(true)
setTimeout(() => setIsCopied(false), 3000)
}

return (
<>
<button className="copy-button" onClick={handleCopy} {...props}>
{isCopied ? (
'Copied!'
) : (
<>
<svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={16}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
{...props}>
<rect x={9} y={9} width={13} height={13} rx={2} ry={2} />
<path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
</svg>
</>
)}
</button>
</>
)
}
69 changes: 37 additions & 32 deletions examples/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ body {
cursor: pointer;
}

.code-container code[class*='language-'] {
.code-container pre[class*='language-'] {
margin-top: -50px;
display: inline-block;
width: auto !important;
Expand All @@ -171,7 +171,6 @@ body {
pointer-events: all;
}


@media only screen and (max-width: 700px) {
.main > .code {
position: relative;
Expand All @@ -188,44 +187,40 @@ body {
bottom: 0;
margin-bottom: -60px;
}
.code-container > code[class*='language-'] {
.code-container > pre[class*='language-'] {
font-size: 0.6rem;
padding: 20px 50px 70px 20px;
border-radius: 10px 10px 0 0 !important;
border-radius: 10px 10px 0 0 !important;
}
.counter {
top: -100px;
right: 20px;
}
}



@media only screen and (max-width: 600px) {
.code-container {
width: 100%;
}

.code-container > code[class*='language-'] {
.code-container > pre[class*='language-'] {
font-size: 0.6rem !important;
padding: 20px 20px 70px;
width: 100% !important;
}

.counter {
top: 70px;
right: 20px;
}

}

@media only screen and (max-height: 600px) {

.code-container {
bottom: 0;
margin-bottom: -60px;
}
.code-container > code[class*='language-'] {
.code-container > pre[class*='language-'] {
font-size: 0.6rem;
padding: 20px 20px 70px;
}
Expand All @@ -238,22 +233,17 @@ body {
}
}
@media only screen and (max-width: 600px) {

.counter {
top: -160px;
right: 20px;
}
}





@media only screen and (max-width: 430px) {
@media only screen and (max-width: 430px) {
.code-container {
margin-bottom: -60px;
}
.code-container > code[class*='language-'] {
.code-container > pre[class*='language-'] {
font-size: 0.6rem;
padding: 20px 20px 70px;
}
Expand All @@ -265,7 +255,7 @@ body {
right: 20px;
}
}
@media only screen and (max-height: 480px) {
@media only screen and (max-height: 480px) {
.counter {
transform: scale(0.8);
transform-origin: bottom right;
Expand All @@ -276,33 +266,30 @@ body {
}

@media only screen and (max-height: 500px) {
.code-container > code[class*='language-'] {
.code-container > pre[class*='language-'] {
font-size: 0.5rem !important;
}

.counter {
top: 40px;
right: 20px;
}
}
}

@media only screen and (max-height: 500px) and (min-width: 600px) {
.counter {
top: 40px;
right: -80px;
}
}
}

@media only screen and (max-height:360px) and (min-width: 600px) {
@media only screen and (max-height: 360px) and (min-width: 600px) {
.counter {
top: 50px;
right: -80px;
}
}
}




.bear {
top: 12.5%;
height: 80% !important;
Expand All @@ -328,8 +315,6 @@ body {
background-image: url('https://uploads.codesandbox.io/uploads/user/b3e56831-8b98-4fee-b941-0e27f39883ab/3n-p-leaves2.png');
}



span.header-left {
font-weight: 700;
text-transform: uppercase;
Expand Down Expand Up @@ -363,7 +348,7 @@ span.header-left {
z-index: 1000;
margin-left: 0;
}
code[class*='language-'] {
pre[class*='language-'] {
font-size: 0.7rem !important;
}
}
Expand Down Expand Up @@ -391,7 +376,6 @@ a.top-right {
top: 40px;
right: 40px;
z-index: 1000;

}

a.bottom-left {
Expand Down Expand Up @@ -444,7 +428,7 @@ a.bottom-right {
}

@media only screen and (max-width: 500px) {
code[class*='language-'] {
pre[class*='language-'] {
font-size: 0.6rem !important;
}
span.header-left {
Expand All @@ -469,3 +453,24 @@ a.bottom-right {
right: 20px;
}
}

.copy-button {
position: absolute;
bottom: 0;
right: 0;
box-shadow: none;
text-decoration: none;
font-size: 14px;
font-family: sans-serif;
line-height: 1;
pointer-events: all;
margin: 10px;
padding: 5px 10px;
width: auto;
border-radius: 5px;
border: 0;
outline: none;
background: transparent;
color: #f8f9fa;
cursor: pointer;
}
12 changes: 12 additions & 0 deletions examples/src/utils/copy-to-clipboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const copyToClipboard = (str) => {
const el = document.createElement('textarea')
el.value = str
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
el.select()
// FIXME: might need to update this with the clipboard API in the future
document.execCommand('copy')
document.body.removeChild(el)
}
10 changes: 5 additions & 5 deletions examples/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8761,6 +8761,11 @@ pretty-format@^26.4.2:
ansi-styles "^4.0.0"
react-is "^16.12.0"

prism-react-renderer@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89"
integrity sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg==

[email protected]:
version "1.23.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
Expand Down Expand Up @@ -9063,11 +9068,6 @@ react-postprocessing@^1.1.4:
postprocessing "^6.17.1"
react-merge-refs "^1.1.0"

react-prism@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/react-prism/-/react-prism-4.3.2.tgz#5c07609539b3ba6f45eb33e7d6a3588df3270c21"
integrity sha512-Z8BzDfWxzhngDtnZFjYj4RgHo7uqiWB4cOCpp//GFEpWbtINbCqHLIpL+q/f8ah5Aokw/uXkBkoLgvYIGgtm4A==

react-promise-suspense@^0.3.2:
version "0.3.3"
resolved "https://registry.yarnpkg.com/react-promise-suspense/-/react-promise-suspense-0.3.3.tgz#b085c7e0ac22b85fd3d605b1c4f181cda4310bc9"
Expand Down

0 comments on commit d2f5af3

Please sign in to comment.