-
-
Notifications
You must be signed in to change notification settings - Fork 28
/
copy-button.ts
96 lines (81 loc) · 2.31 KB
/
copy-button.ts
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
85
86
87
88
89
90
91
92
93
94
95
96
import { LitElement, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { msg, localized } from "@lit/localize";
/**
* Copy text to clipboard on click
*
* Usage example:
* ```ts
* <btrix-copy-button .value=${value}></btrix-copy-button>
* ```
* Or:
* ```ts
* <btrix-copy-button .getValue=${() => value}></btrix-copy-button>
* ```
*
* @event on-copied
*/
@localized()
@customElement("btrix-copy-button")
export class CopyButton extends LitElement {
@property({ type: String })
value?: string;
@property({ type: String })
name?: string;
@property({ type: String })
content?: string;
@property({ attribute: false })
getValue?: () => string | undefined;
@property({ type: Boolean })
hoist = false;
@state()
private isCopied = false;
timeoutId?: number;
static copyToClipboard(value: string) {
void navigator.clipboard.writeText(value);
}
disconnectedCallback() {
window.clearTimeout(this.timeoutId);
super.disconnectedCallback();
}
render() {
return html`
<sl-tooltip
content=${this.isCopied
? msg("Copied to clipboard!")
: this.content
? this.content
: msg("Copy")}
?hoist=${this.hoist}
@sl-hide=${this.stopProp}
@sl-after-hide=${this.stopProp}
>
<sl-icon-button
name=${this.isCopied ? "check-lg" : this.name ? this.name : "files"}
label=${msg("Copy to clipboard")}
@click=${this.onClick}
?disabled=${!this.value && !this.getValue}
></sl-icon-button>
</sl-tooltip>
`;
}
private onClick() {
const value = (this.getValue ? this.getValue() : this.value) || "";
CopyButton.copyToClipboard(value);
this.isCopied = true;
this.dispatchEvent(new CustomEvent("on-copied", { detail: value }));
this.timeoutId = window.setTimeout(() => {
this.isCopied = false;
const button = this.shadowRoot?.querySelector("sl-icon-button");
button?.blur(); // Remove focus from the button to set it back to its default state
}, 3000);
}
/**
* Stop propgation of sl-tooltip events.
* Prevents bug where sl-dialog closes when tooltip closes
* https://github.com/shoelace-style/shoelace/issues/170
*/
private stopProp(e: Event) {
e.stopPropagation();
}
}