75 lines
1.3 KiB
Vue
75 lines
1.3 KiB
Vue
<template>
|
|
<div :class="[cn.b(), cn.is('active', pressed)]">
|
|
<UiButton
|
|
right-icon="s-copy"
|
|
size="small"
|
|
type="link"
|
|
color="secondary"
|
|
:class="cn.e('default')"
|
|
@click="copyHandler()"
|
|
>
|
|
<template
|
|
v-if="title"
|
|
#default
|
|
>
|
|
{{ title }}
|
|
</template>
|
|
</UiButton>
|
|
|
|
<div :class="cn.e('copied')">
|
|
<span v-if="pressedTitle">
|
|
{{ pressedTitle }}
|
|
</span>
|
|
|
|
<UiIconSCheck />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import UiButton from '../button/index.vue'
|
|
import useClassname from '../../composables/use-classname'
|
|
|
|
export interface Props {
|
|
title?: string
|
|
pressedTitle?: string
|
|
value: string | (() => Promise<string>)
|
|
}
|
|
|
|
defineOptions({
|
|
name: 'UiCopyButton',
|
|
})
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
title: 'Copy',
|
|
pressedTitle: 'Copied',
|
|
})
|
|
|
|
const cn = useClassname('ui-copy-button')
|
|
|
|
const pressed = ref(false)
|
|
|
|
async function copyHandler() {
|
|
pressed.value = true
|
|
|
|
const valueToCopy
|
|
= typeof props.value === 'function' ? props.value() : props.value
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(await valueToCopy)
|
|
}
|
|
catch {}
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 2000))
|
|
pressed.value = false
|
|
}
|
|
|
|
defineExpose({
|
|
copy: copyHandler,
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@use 'styles';
|
|
</style>
|