Files
OCS_service/app/components/CopyCom.vue
T

79 lines
2.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- app/components/CopyCom.vue - 通用复制按钮 -->
<script lang="ts" setup>
import { Check, Copy } from "lucide-vue-next";
import type { HTMLAttributes } from "vue";
import type { ButtonVariants } from "@/components/ui/button";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { copy } from "@/utils";
const {
text = "",
class: className,
variant = "outline",
size = "sm",
timeout = 2000,
disableDefaultCopy = false,
disabled = false
} = defineProps<{
/** 要复制的文本 */
text?: string;
// eslint-disable-next-line vue/require-default-prop
class?: HTMLAttributes["class"] | undefined;
variant?: ButtonVariants["variant"];
size?: ButtonVariants["size"];
/** 复制成功后恢复的延迟毫秒数,默认 2000 */
timeout?: number;
/** 禁用内置复制行为,只触发状态变化(外部自行处理复制) */
disableDefaultCopy?: boolean;
/** 禁用按鈕,不可点击且展示禁用样式 */
disabled?: boolean;
}>();
const emit = defineEmits<{
copy: [text: string];
}>();
const isCopied = ref(false);
const handleCopy = () => {
if (disabled) return;
if (!disableDefaultCopy) {
copy(text);
}
emit("copy", text);
isCopied.value = true;
setTimeout(() => {
isCopied.value = false;
}, timeout);
};
defineExpose({ isCopied });
</script>
<template>
<Button
type="button"
:variant="variant"
:size="size"
:disabled="disabled"
:class="cn('relative overflow-hidden pl-7', className)"
@click.prevent.stop="handleCopy"
>
<!-- 复制成功图标未复制时向上移出复制后滑入 -->
<Check
class="absolute size-3.5 transition-transform duration-200 left-2.5"
:class="isCopied ? 'translate-y-0' : '-translate-y-6'"
/>
<!-- 默认复制图标复制后向下移出 -->
<Copy
class="absolute size-3.5 transition-transform duration-200 left-2.5"
:class="isCopied ? 'translate-y-6' : 'translate-y-0'"
/>
<slot :is-copied="isCopied">
<span>复制</span>
</slot>
</Button>
</template>