Rocket Copy Button Pro
Rocket is currently in beta.
Explanation #
The demo page owns the editable text and passes it to the component as a prop. The component keeps only its ephemeral copied state in setup() so it can show feedback and clear the timeout.
Usage Example #
Rocket Component #
1import { rocket } from 'datastar'
2
3rocket('copy-button', {
4 mode: 'light',
5 props: ({ string }) => ({
6 code: string,
7 }),
8 setup: ({ $$, cleanup, host, props }) => {
9 $$.copied = false
10 let timer = 0
11
12 host.addEventListener('click', onClick)
13
14 cleanup(() => {
15 clearTimeout(timer)
16 host.removeEventListener('click', onClick)
17 })
18
19 async function onClick(evt) {
20 if (!(evt.target instanceof Element)) return
21 if (!evt.target.closest('button.copy-button')) return
22 await navigator.clipboard.writeText(props.code ?? '')
23 $$.copied = true
24 clearTimeout(timer)
25 timer = setTimeout(() => {
26 $$.copied = false
27 }, 2000)
28 }
29 },
30 render: ({ html }) => html`
31 <div class="copy-button-wrapper">
32 <button
33 class="copy-button small"
34 type="button"
35 title="Copy code"
36 >
37 <iconify-icon
38 noobserver
39 data-attr:icon="'pixelarticons:' + ($$copied ? 'section-copy' : 'copy')"
40 ></iconify-icon>
41 </button>
42 <span data-show="$$copied" class="copy-popover">Copied!</span>
43 </div>
44 `,
45})