initial
This commit is contained in:
74
layers/ui/components/copy-button/index.vue
Normal file
74
layers/ui/components/copy-button/index.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user