46 lines
1.2 KiB
Plaintext
46 lines
1.2 KiB
Plaintext
---
|
|
import { cn } from '../lib/cn'
|
|
|
|
import Button, { type ButtonProps } from './Button.astro'
|
|
|
|
import type { Optional } from 'ts-toolbelt/out/Object/Optional'
|
|
|
|
type Props = Optional<ButtonProps<'button'>, 'icon' | 'label'> & {
|
|
copyText: string
|
|
}
|
|
|
|
const { copyText, class: className, icon, label, ...buttonProps } = Astro.props
|
|
---
|
|
|
|
<Button
|
|
data-copy-text={copyText}
|
|
data-copy-button
|
|
{...buttonProps}
|
|
label={label ?? 'Copy'}
|
|
icon={icon ?? 'ri:clipboard-line'}
|
|
class={cn(['no-js:hidden', className])}
|
|
/>
|
|
|
|
<script>
|
|
document.addEventListener('astro:page-load', () => {
|
|
const buttons = document.querySelectorAll<HTMLButtonElement>('[data-copy-button]')
|
|
buttons.forEach((button) => {
|
|
button.addEventListener('click', () => {
|
|
const text = button.dataset.copyText
|
|
if (text === undefined) {
|
|
throw new Error('Copy button must have a data-copy-text attribute')
|
|
}
|
|
navigator.clipboard.writeText(text)
|
|
|
|
const span = button.querySelector<HTMLSpanElement>('span')
|
|
if (span) {
|
|
span.textContent = 'Copied'
|
|
setTimeout(() => {
|
|
span.textContent = 'Copy'
|
|
}, 2000)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
</script>
|