This commit is contained in:
Nadar
2026-03-17 13:24:22 +03:00
commit 82e5ac9d81
554 changed files with 29637 additions and 0 deletions

View 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>

View File

@@ -0,0 +1,52 @@
@use '../../styles/variables' as *;
@use '../../styles/mixins' as *;
.ui-copy-button {
$self: &;
@include txt-r-m;
display: inline-block;
position: relative;
height: 16px;
text-align: left;
width: min-content;
user-select: none;
vertical-align: middle;
&__default,
&__copied {
transition: .2s ease-in-out;
transition-property: transform, opacity;
transform-origin: center;
#{$self}.is-active & {
transform: translateY(-16px);
}
}
&__default {
opacity: 1;
#{$self}.is-active & {
opacity: 0;
pointer-events: none;
}
}
&__copied {
@include txt-r-m;
display: inline-flex;
align-items: center;
gap: 8px;
white-space: nowrap;
color: $clr-cyan-500;
opacity: 0;
pointer-events: none;
#{$self}.is-active & {
opacity: 1;
}
}
}