Skip to content

Commit

Permalink
✨ Add copy-to-clipboard button
Browse files Browse the repository at this point in the history
  • Loading branch information
stormwarning committed Sep 13, 2017
1 parent 12ac6ba commit b5a0a95
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 6 deletions.
43 changes: 37 additions & 6 deletions components/Gradient.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
<template>
<figure class="flex pa5" :style="{ backgroundImage: gradientCSS }">
<div class="dn db-l w-100 mw6 ma-auto bg-white">
<div class="pa4 f6 ttu tracked lh-solid black-90">Result</div>
<pre class="ph4 pv5 mt0 nr4 mb4 nl4 ttl ws-normal bg-light-gray lh-copy"><code>{{ gradientCSS }}</code></pre>
<div class="dn db-l w-100 mw6 ma-auto bg-white br1 overflow-hidden">
<button class="button-reset w-100 pa4 f7 f7-ns ttu tracked lh-solid black-90 bg-white ba bw2 b--white tl pointer hide-child relative" @click="copyCSS(gradientCSS)">
<div class="button-bg child absolute absolute--fill" :style="{ backgroundImage: gradientCSS }"></div>
<div class="button-text absolute absolute--fill flex ma1 bg-white">
<div class="ma-auto">
<svg class="relative w1 h1 mr2 v-mid" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" />
<rect x="8" y="2" width="8" height="4" rx="1" ry="1" />
</svg>
<span class="relative lh-solid v-mid">{{ copyButtonText }}</span>
</div>
</div>
</button>
<pre class="source-code ph4 pv5 ma0 ttl ws-normal bg-light-gray"><code>{{ gradientCSS }}</code></pre>
</div>
</figure>
</template>

<script>
import chroma from 'chroma-js'
import { copyTextToClipboard } from '../utils/clipboard'
export default {
Expand All @@ -18,6 +30,12 @@ export default {
'mode',
],
data () {
return {
copyButtonText: 'Copy CSS',
}
},
computed: {
gradientCSS: function () {
const dir = `${this.dir}deg`
Expand Down Expand Up @@ -45,6 +63,14 @@ export default {
},
methods: {
copyCSS (code) {
copyTextToClipboard(code)
this.copyButtonText = 'Copied!'
setTimeout(() => {
this.copyButtonText = 'Copy CSS'
}, 2000)
},
},
}
</script>
Expand All @@ -56,11 +82,16 @@ figure {
}
figure>div {
box-shadow: 0 50px 50px 0 rgba(0, 0, 0, 0.10);
/* box-shadow: 0 50px 50px 0 rgba(0, 0, 0, 0.10); */
box-shadow: rgba(0, 0, 0, 0.12) 0px 2px 10px, 0 50px 50px 0 rgba(0, 0, 0, 0.10);
}
pre {
box-shadow: 0 50px 50px 0 rgba(0, 0, 0, 0.10);
.source-code {
/* color: #e2e6e8;
background-color: #16191b; */
/* box-shadow: 0 50px 50px 0 rgba(0, 0, 0, 0.10); */
/* box-shadow: rgba(0, 0, 0, 0.12) 0px 2px 10px, rgba(0, 0, 0, 0.16) 0px 2px 5px; */
line-height: 2;
}
.ma-auto {
Expand Down
54 changes: 54 additions & 0 deletions utils/clipboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// From: https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
export function copyTextToClipboard (text) {
const textArea = document.createElement('textarea')

//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a flash,
// so some of these are just precautions. However in IE the element
// is visible whilst the popup box asking the user for permission for
// the web page to copy to the clipboard.
//

// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed'
textArea.style.top = 0
textArea.style.left = 0

// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em'
textArea.style.height = '2em'

// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0

// Clean up any borders.
textArea.style.border = 'none'
textArea.style.outline = 'none'
textArea.style.boxShadow = 'none'

// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent'

textArea.value = text

document.body.appendChild(textArea)

textArea.select()

try {
document.execCommand('copy')
} catch (err) {
console.error('Unable to copy text')
}

document.body.removeChild(textArea)
}

0 comments on commit b5a0a95

Please sign in to comment.