PropShow Kit Logo
Components

Copy

Copy button component, supports custom styles and tooltip text.

Component Example

Your browser does not support Clipboard APIDefault
Your browser does not support Clipboard APISmall
Your browser does not support Clipboard APISecondary Variant

Install using CLI

Component Source

Copy.vue
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue'

import { CopyCheckIcon, CopyIcon } from '@lucide/vue'
import { useClipboard } from '@vueuse/core'

import type { ButtonVariants } from '@/components/ui/button'

import { Button } from '@/components/ui/button'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'

import { copyVariants } from '.'

interface Props {
    content: string
    size?: 'sm' | 'default'
    variant?: ButtonVariants['variant']
    class?: HTMLAttributes['class']
    copyTooltipText?: string
    copiedTooltipText?: string
}

const props = withDefaults(defineProps<Props>(), {
    size: 'default',
    variant: 'outline',
    copyTooltipText: 'Copy',
    copiedTooltipText: 'Copied',
})

const iconSize = computed(() => {
    return props.size === 'sm' ? 'sm' : 'default'
})

const size = computed(() => {
    return props.size === 'sm' ? 'sm' : 'icon'
})

const source = computed(() => props.content)

const { copy, copied, isSupported } = useClipboard({ source })
</script>

<template>
    <span v-if="isSupported">
        <TooltipProvider>
            <Tooltip>
                <TooltipTrigger as-child>
                    <Button :variant="props.variant" :size="size" :class="cn(props.class)" @click="copy(source)">
                        <CopyIcon v-if="!copied" :class="cn(copyVariants({ iconSize }))" />
                        <CopyCheckIcon v-else :class="cn(copyVariants({ iconSize }))" />
                    </Button>
                </TooltipTrigger>
                <TooltipContent>
                    <p v-if="!copied">{{ props.copyTooltipText }}: {{ props.content }}</p>
                    <p v-else>{{ props.copiedTooltipText }}: {{ props.content }}</p>
                </TooltipContent>
            </Tooltip>
        </TooltipProvider>
    </span>
    <span v-else>Your browser does not support Clipboard API</span>
</template>
index.ts
import type { VariantProps } from 'class-variance-authority'

import { cva } from 'class-variance-authority'

export { default as Copy } from './Copy.vue'

export const copyVariants = cva(
    '',
    {
        variants: {
            iconSize: {
                default: 'size-4',
                sm: 'size-3',
            },
        },
        defaultVariants: {
            iconSize: 'default',
        },
    },
)

export type CopyVariants = VariantProps<typeof copyVariants>

Props

Prop Type Default Required Description
contentstring-YesContent to copy
size'sm' | 'default'defaultNoButton size
variantButtonVariants['variant']outlineNoButton style variant
copyTooltipTextstringCopyNoTooltip text before copying
copiedTooltipTextstringCopiedNoTooltip text after copying
Copyright © 2026