-
Notifications
You must be signed in to change notification settings - Fork 269
Expand file tree
/
Copy pathcopy.mjs
More file actions
84 lines (68 loc) · 2.05 KB
/
copy.mjs
File metadata and controls
84 lines (68 loc) · 2.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import ClipboardJS from 'clipboard'
import { Component } from 'govuk-frontend'
/**
* Copy button for code examples
*/
class Copy extends Component {
static moduleName = 'app-copy'
/**
* Check if ClipboardJS is supported
*/
static checkSupport() {
Component.checkSupport()
if (!ClipboardJS.isSupported()) {
throw Error('ClipboardJS not supported in this browser')
}
}
/**
* @param {Element} $module - HTML element
*/
constructor($module) {
super($module)
this.$pre = this.$root.querySelector('pre')
// TODO: Throw once GOV.UK Frontend exports its errors
/** @type {number | null} */
this.resetTimeoutId = null
this.$button = document.createElement('button')
this.$button.className = 'app-copy-button'
this.$button.textContent = 'Copy code'
this.$status = document.createElement('span')
this.$status.className = 'govuk-visually-hidden'
this.$status.setAttribute('aria-live', 'assertive')
this.$root.prepend(this.$status)
this.$root.prepend(this.$button)
const $clipboard = new ClipboardJS(this.$button, {
target: () => this.$pre
})
$clipboard.on('success', (event) => this.successAction(event))
$clipboard.on('error', (event) => this.resetAction(event))
}
/**
* Copy to clipboard success
*
* @param {import('clipboard').Event} event - Clipboard event
*/
successAction(event) {
this.$button.textContent = this.$status.textContent = 'Code copied'
// Reset button after 5 seconds
this.resetAction(event, 5000)
}
/**
* Copy to clipboard reset
*
* @param {import('clipboard').Event} event - Clipboard event
* @param {number} [timeout] - Button text reset timeout
*/
resetAction(event, timeout = 0) {
event.clearSelection()
if (this.resetTimeoutId) {
window.clearTimeout(this.resetTimeoutId)
}
// Reset button after timeout
this.resetTimeoutId = window.setTimeout(() => {
this.$button.textContent = 'Copy code'
this.$status.textContent = ''
}, timeout)
}
}
export default Copy