Files
components/clipboard-copy.tsx
1'use client'
2import React from 'react'
3import { Check, Copy } from 'lucide-react'
4
5import { cn } from '@/lib/utils'
6import { Card, CardContent } from '@/components/ui/card'
7import { Label } from '@/components/ui/label'
8
9export function copyToClipboardWithMeta(value: string) {
10    navigator.clipboard.writeText(value)
11}
12
13const ClipboardCopy01 = ({
14    content = 'This is sample text',
15    ...props
16}: {
17    content: string
18}) => {
19    const [hasCopied, setHasCopied] = React.useState(false)
20
21    return (
22        <Card className="max-w-md rounded-2xl border border-gray-200 bg-white shadow-sm">
23            <CardContent>
24                <div className="flex items-center justify-between gap-8">
25                    <Label className="text-gray text-sm font-medium">
26                        {content}
27                    </Label>
28                    <button
29                        onClick={() => {
30                            copyToClipboardWithMeta(content)
31                            setHasCopied(true)
32                            setTimeout(() => {
33                                setHasCopied(false)
34                            }, 2000)
35                        }}
36                        className={cn(
37                            'ring-border relative rounded-md bg-white p-1.5 ring-1 transition-all duration-200 outline-none ring-inset',
38                            'text-black/50 hover:text-black/70',
39                            // 'opacity-0 group-hover:opacity-100',
40                        )}
41                        aria-label="Copy code to clipboard"
42                        {...props}
43                    >
44                        {hasCopied ? (
45                            <Check className="h-4 w-4 text-green-400" />
46                        ) : (
47                            <Copy className="h-4 w-4" />
48                        )}
49                    </button>
50                </div>
51            </CardContent>
52        </Card>
53    )
54}
55
56export ClipboardCopy01
57
Simple clipboard copy
clipboard-copy-01
Files
components/clipboard-copy.tsx
1'use client'
2import React from 'react'
3import { Check, Copy } from 'lucide-react'
4
5import { cn } from '@/lib/utils'
6import { Card, CardContent } from '@/components/ui/card'
7import { Label } from '@/components/ui/label'
8
9export function copyToClipboardWithMeta(value: string) {
10    navigator.clipboard.writeText(value)
11}
12
13const ClipboardCopy02 = ({
14    content = 'This is sample text',
15    ...props
16}: {
17    content: string
18}) => {
19    const [hasCopied, setHasCopied] = React.useState(false)
20
21    return (
22        <Card className="max-w-md rounded-2xl border border-gray-200 bg-white shadow-sm">
23            <CardContent>
24                <div className="flex items-center justify-between gap-8">
25                    <Label className="text-gray text-sm font-medium">
26                        {content}
27                    </Label>
28                    <button
29                        onClick={() => {
30                            copyToClipboardWithMeta(content)
31                            setHasCopied(true)
32                            setTimeout(() => {
33                                setHasCopied(false)
34                            }, 2000)
35                        }}
36                        className={cn(
37                            'ring-border relative rounded-md bg-white p-1.5 ring-1 transition-all duration-200 outline-none ring-inset',
38                            'text-black/50 hover:text-black/70',
39                            // 'opacity-0 group-hover:opacity-100',
40                        )}
41                        aria-label="Copy code to clipboard"
42                        {...props}
43                    >
44                        {hasCopied ? (
45                            <Check className="h-4 w-4 text-green-400" />
46                        ) : (
47                            <Copy className="h-4 w-4" />
48                        )}
49                        {hasCopied && (
50                            <div className="shadow-3xl absolute -top-9 left-1/2 -translate-x-1/2 rounded-md bg-gray-100 text-xs font-medium text-black">
51                                <div className="before:shadow-3xl relative px-2 py-1 before:absolute before:-bottom-1 before:left-1/2 before:-z-1 before:size-2 before:-translate-x-1/2 before:rotate-45 before:skew-2 before:bg-gray-100 after:absolute after:bottom-0 after:left-1/2 after:size-5 after:-translate-x-1/2 after:bg-gray-100">
52                                    <span className="relative z-1">
53                                        Copied!
54                                    </span>
55                                </div>
56                            </div>
57                        )}
58                    </button>
59                </div>
60            </CardContent>
61        </Card>
62    )
63}
64
65export ClipboardCopy02
66
Clipboard with tooltip
clipboard-copy-02
Files
components/clipboard-copy.tsx
1'use client'
2import React from 'react'
3import { Check, Copy } from 'lucide-react'
4
5import { cn } from '@/lib/utils'
6
7export function copyToClipboardWithMeta(value: string) {
8    navigator.clipboard.writeText(value)
9}
10
11const ClipboardCopy03 = ({
12    content = 'This is sample text',
13    ...props
14}: {
15    content: string
16}) => {
17    const [hasCopied, setHasCopied] = React.useState(false)
18    const [textVariantCopied, setTextVariantCopied] = React.useState(false)
19    const [coloredVariantCopied, setColoredVariantCopied] =
20        React.useState(false)
21
22    return (
23        <div className="flex max-w-md items-center gap-2">
24            <button
25                onClick={() => {
26                    copyToClipboardWithMeta(content)
27                    setHasCopied(true)
28                    setTimeout(() => {
29                        setHasCopied(false)
30                    }, 2000)
31                }}
32                className={cn(
33                    'ring-border relative rounded-md bg-white p-1.5 ring-1 transition-all duration-200 outline-none ring-inset',
34                    'text-black/50 hover:text-black/70',
35                    // 'opacity-0 group-hover:opacity-100',
36                )}
37                aria-label="Copy code to clipboard"
38                {...props}
39            >
40                {hasCopied ? (
41                    <Check className="h-4 w-4 text-green-400" />
42                ) : (
43                    <Copy className="h-4 w-4" />
44                )}
45                {hasCopied && (
46                    <div className="shadow-3xl absolute -top-9 left-1/2 -translate-x-1/2 rounded-md bg-gray-100 text-xs font-medium text-black">
47                        <div className="before:shadow-3xl relative px-2 py-1 before:absolute before:-bottom-1 before:left-1/2 before:-z-1 before:size-2 before:-translate-x-1/2 before:rotate-45 before:skew-2 before:bg-gray-100 after:absolute after:bottom-0 after:left-1/2 after:size-5 after:-translate-x-1/2 after:bg-gray-100">
48                            <span className="relative z-1">Copied!</span>
49                        </div>
50                    </div>
51                )}
52            </button>
53            <button
54                onClick={() => {
55                    copyToClipboardWithMeta(content)
56                    setTextVariantCopied(true)
57                    setTimeout(() => {
58                        setTextVariantCopied(false)
59                    }, 2000)
60                }}
61                className={cn(
62                    'ring-border relative flex items-center gap-2 rounded-md bg-white p-1.5 ring-1 transition-all duration-200 outline-none ring-inset',
63                    'text-black/50 hover:text-black/70',
64                    // 'opacity-0 group-hover:opacity-100',
65                )}
66                aria-label="Copy code to clipboard"
67                {...props}
68            >
69                {textVariantCopied ? (
70                    <Check className="h-4 w-4 text-green-400" />
71                ) : (
72                    <Copy className="h-4 w-4" />
73                )}
74                With Text
75                {textVariantCopied && (
76                    <div className="shadow-3xl absolute -top-9 left-1/2 -translate-x-1/2 rounded-md bg-gray-100 text-xs font-medium text-black">
77                        <div className="before:shadow-3xl relative px-2 py-1 before:absolute before:-bottom-1 before:left-1/2 before:-z-1 before:size-2 before:-translate-x-1/2 before:rotate-45 before:skew-2 before:bg-gray-100 after:absolute after:bottom-0 after:left-1/2 after:size-5 after:-translate-x-1/2 after:bg-gray-100">
78                            <span className="relative z-1">Copied!</span>
79                        </div>
80                    </div>
81                )}
82            </button>
83            <button
84                onClick={() => {
85                    copyToClipboardWithMeta(content)
86                    setColoredVariantCopied(true)
87                    setTimeout(() => {
88                        setColoredVariantCopied(false)
89                    }, 2000)
90                }}
91                className={cn(
92                    'ring-border relative flex items-center gap-2 rounded-md bg-white p-1.5 ring-1 transition-all duration-200 outline-none ring-inset',
93                    'text-black/50',
94                    coloredVariantCopied
95                        ? 'bg-success text-white'
96                        : 'hover:text-black/70',
97                    // 'opacity-0 group-hover:opacity-100',
98                )}
99                aria-label="Copy code to clipboard"
100                {...props}
101            >
102                {coloredVariantCopied ? (
103                    <Check className="h-4 w-4 text-green-400" />
104                ) : (
105                    <Copy className="h-4 w-4" />
106                )}
107                With Color
108                {coloredVariantCopied && (
109                    <div className="shadow-3xl absolute -top-9 left-1/2 -translate-x-1/2 rounded-md bg-gray-100 text-xs font-medium text-black">
110                        <div className="before:shadow-3xl relative px-2 py-1 before:absolute before:-bottom-1 before:left-1/2 before:-z-1 before:size-2 before:-translate-x-1/2 before:rotate-45 before:skew-2 before:bg-gray-100 after:absolute after:bottom-0 after:left-1/2 after:size-5 after:-translate-x-1/2 after:bg-gray-100">
111                            <span className="relative z-1">Copied!</span>
112                        </div>
113                    </div>
114                )}
115            </button>
116        </div>
117    )
118}
119
120export ClipboardCopy03
121
Only button clipboard
clipboard-copy-03
Files
components/clipboard-copy.tsx
1'use client'
2import React from 'react'
3import { Copy } from 'lucide-react'
4import { toast } from 'sonner'
5
6import { cn } from '@/lib/utils'
7
8export function copyToClipboardWithMeta(value: string) {
9    navigator.clipboard.writeText(value)
10}
11
12const ClipboardCopy04 = ({
13    content = 'This is sample text',
14    ...props
15}: {
16    content: string
17}) => {
18    return (
19        <div className="flex max-w-md items-center gap-2">
20            <button
21                onClick={() => {
22                    copyToClipboardWithMeta(content)
23                    toast.success('Copied to clipboard')
24                }}
25                className={cn(
26                    'ring-border relative rounded-md bg-white p-1.5 ring-1 transition-all duration-200 outline-none ring-inset',
27                    'flex items-center gap-2 text-black/50 hover:text-black/70',
28                    // 'opacity-0 group-hover:opacity-100',
29                )}
30                aria-label="Copy code to clipboard"
31                {...props}
32            >
33                <Copy className="h-4 w-4" />
34                With Toast
35            </button>
36        </div>
37    )
38}
39
40export ClipboardCopy04
41
Clipboard with toast
clipboard-copy-04
Files
components/clipboard-copy.tsx
1'use client'
2import React from 'react'
3import { Check, Copy } from 'lucide-react'
4
5import { cn } from '@/lib/utils'
6
7export function copyToClipboardWithMeta(value: string) {
8    navigator.clipboard.writeText(value)
9}
10
11const ClipboardCopy05 = ({
12    content = 'npm i xyz',
13    ...props
14}: {
15    content: string
16}) => {
17    const [hasCopied, setHasCopied] = React.useState(false)
18    return (
19        <code className="flex w-full max-w-lg items-center justify-between gap-6 rounded-xl border border-gray-200 bg-[#0e1217] p-3 font-mono text-[#a8b3cf] shadow-sm">
20            {content}
21            <button
22                onClick={() => {
23                    copyToClipboardWithMeta(content)
24                    setHasCopied(true)
25                    setTimeout(() => {
26                        setHasCopied(false)
27                    }, 2000)
28                }}
29                className={cn(
30                    'relative rounded-md bg-white/20 p-1.5 transition-all duration-200 outline-none ring-inset',
31                    'flex items-center gap-2',
32                    hasCopied ? 'text-[#a8b3cf]' : 'hover:text-[#a8b3cf]/50',
33                )}
34                aria-label="Copy code to clipboard"
35                {...props}
36            >
37                {hasCopied ? (
38                    <Check className="h-4 w-4 text-green-400" />
39                ) : (
40                    <Copy className="h-4 w-4" />
41                )}
42                {hasCopied && (
43                    <div className="shadow-3xl absolute -top-9 left-1/2 -translate-x-1/2 rounded-md bg-gray-100 text-xs font-medium text-black">
44                        <div className="before:shadow-3xl relative px-2 py-1 before:absolute before:-bottom-1 before:left-1/2 before:-z-1 before:size-2 before:-translate-x-1/2 before:rotate-45 before:skew-2 before:bg-gray-100 after:absolute after:bottom-0 after:left-1/2 after:size-5 after:-translate-x-1/2 after:bg-gray-100">
45                            <span className="relative z-1">Copied!</span>
46                        </div>
47                    </div>
48                )}
49            </button>
50        </code>
51    )
52}
53
54export ClipboardCopy05
55
Clipboard with code block
clipboard-copy-05
Files
components/clipboard-copy.tsx
1'use client'
2
3import * as React from 'react'
4import { ClipboardCheck, ClipboardList } from 'lucide-react'
5import { toast } from 'sonner'
6
7import { Button } from '@/components/ui/button'
8
9export function CopyClipboard06() {
10    const [copied, setCopied] = React.useState(false)
11
12    const code = `'use client'
13
14    import Link from 'next/link'
15    import { Navbar } from 'flowbite-react'
16
17    function Component() {
18    return (
19        <Navbar fluid rounded>
20        <Navbar.Brand as={Link} href="https://flowbite-react.com">
21            <img
22            src="/favicon.svg"
23            className="mr-3 h-6 sm:h-9"
24            alt="Flowbite React Logo"
25            />
26            <span className="self-center whitespace-nowrap text-xl font-semibold">
27            Flowbite React
28            </span>
29        </Navbar.Brand>
30        </Navbar>
31    )
32    }`
33
34    const handleCopy = async () => {
35        await navigator.clipboard.writeText(code)
36        toast.success('Copied to clipboard')
37        setCopied(true)
38        setTimeout(() => setCopied(false), 1500)
39    }
40
41    return (
42        <div className="w-full max-w-lg">
43            <p className="text-heading mb-2 text-sm font-medium">
44                Card example with CTA button:
45            </p>
46
47            <div className="border-border bg-neutral-secondary-medium relative h-64 rounded-xl border p-4">
48                <Button
49                    size="sm"
50                    variant="outline"
51                    onClick={handleCopy}
52                    className="absolute top-2 right-2 flex items-center gap-1 bg-white"
53                >
54                    {copied ? (
55                        <>
56                            <ClipboardCheck className="h-4 w-4" />
57                            Copied
58                        </>
59                    ) : (
60                        <>
61                            <ClipboardList className="h-4 w-4" />
62                            Copy
63                        </>
64                    )}
65                </Button>
66
67                <pre className="h-full overflow-auto text-sm">
68                    <code className="whitespace-pre">{code}</code>
69                </pre>
70            </div>
71
72            <p className="text-body mt-2.5 text-sm">
73                Configure Tailwind CSS and Flowbite before copying the code
74            </p>
75        </div>
76    )
77}
78
Clipboard with source code block
clipboard-copy-06
Files
components/clipboard-copy.tsx
1'use client'
2
3import * as React from 'react'
4import { ClipboardCheck, ClipboardList } from 'lucide-react'
5import { toast } from 'sonner'
6
7import { Input } from '@/components/ui/input'
8
9export function CopyClipboard07() {
10    const [value] = React.useState('npx create-next-app@latest')
11    const [copied, setCopied] = React.useState(false)
12
13    const handleCopy = async () => {
14        await navigator.clipboard.writeText(value)
15        toast.success('Copied to clipboard')
16        setCopied(true)
17        setTimeout(() => setCopied(false), 1500)
18    }
19
20    return (
21        <div className="flex items-center gap-2 rounded-xl p-3">
22            <Input
23                value={value}
24                readOnly
25                className="w-full"
26                iconRight={
27                    copied ? (
28                        <ClipboardCheck className="h-4 w-4" />
29                    ) : (
30                        <ClipboardList
31                            onClick={handleCopy}
32                            className="h-4 w-4 cursor-pointer text-gray-500"
33                        />
34                    )
35                }
36            />
37        </div>
38    )
39}
40
Clipboard with input
clipboard-copy-07
Files
components/clipboard-copy.tsx
1'use client'
2
3import * as React from 'react'
4import { ClipboardCheck, ClipboardList } from 'lucide-react'
5import { toast } from 'sonner'
6
7import {
8    InputGroup,
9    InputGroupAddon,
10    InputGroupInput,
11} from '@/components/ui/input-group'
12
13export function CopyClipboard08() {
14    const value = 'sk_live_8f9d2aXExampleKey'
15    const [copied, setCopied] = React.useState(false)
16
17    const handleCopy = async () => {
18        await navigator.clipboard.writeText(value)
19        toast.success('Copied to clipboard')
20        setCopied(true)
21        setTimeout(() => setCopied(false), 1500)
22    }
23
24    return (
25        <div className="w-[420px] space-y-1">
26            <p className="text-sm font-medium">Your API Key</p>
27
28            <InputGroup>
29                <InputGroupAddon align="inline-start">KEY</InputGroupAddon>
30                <InputGroupInput value={value} readOnly />
31                <InputGroupAddon align="inline-end">
32                    {copied ? (
33                        <ClipboardCheck className="text-primary h-4 w-4 bg-white" />
34                    ) : (
35                        <ClipboardList
36                            className="h-4 w-4 cursor-pointer bg-white text-gray-500"
37                            onClick={handleCopy}
38                        />
39                    )}
40                </InputGroupAddon>
41            </InputGroup>
42            <p className="text-muted-foreground text-xs">
43                Keep this key secret. Do not share it publicly.
44            </p>
45        </div>
46    )
47}
48
Clipboard with input group
clipboard-copy-08
Files
components/clipboard-copy.tsx
1'use client'
2
3import * as React from 'react'
4import { Clipboard, ClipboardCheck, Share2 } from 'lucide-react'
5import { toast } from 'sonner'
6
7import { Button } from '@/components/ui/button'
8import {
9    Dialog,
10    DialogClose,
11    DialogContent,
12    DialogFooter,
13    DialogHeader,
14    DialogTitle,
15    DialogTrigger,
16} from '@/components/ui/dialog'
17import { Input } from '@/components/ui/input'
18
19export function CopyClipboard09() {
20    const inviteUrl = 'https://app.example.com/invite/8f3k2'
21    const [copied, setCopied] = React.useState(false)
22
23    const handleCopy = async () => {
24        await navigator.clipboard.writeText(inviteUrl)
25        toast.success('Copied to clipboard')
26        setCopied(true)
27        setTimeout(() => setCopied(false), 1500)
28    }
29
30    return (
31        <Dialog>
32            <DialogTrigger asChild>
33                <Button
34                    variant="outline"
35                    className="inline-flex items-center gap-1.5"
36                >
37                    <Share2 className="h-4 w-4" />
38                    Invite members
39                </Button>
40            </DialogTrigger>
41
42            <DialogContent className="sm:max-w-lg">
43                <DialogHeader>
44                    <DialogTitle>Invite team members</DialogTitle>
45                </DialogHeader>
46
47                <div className="flex flex-col gap-4">
48                    <label className="text-foreground text-sm font-medium">
49                        Share this invitation link
50                    </label>
51
52                    <div className="relative">
53                        <Input value={inviteUrl} readOnly className="pr-12" />
54
55                        <button
56                            onClick={handleCopy}
57                            className="text-muted-foreground hover:text-foreground hover:bg-muted absolute top-1/2 right-1.5 -translate-y-1/2 rounded-md p-2"
58                        >
59                            {copied ? (
60                                <ClipboardCheck className="text-primary h-4 w-4" />
61                            ) : (
62                                <Clipboard className="h-4 w-4" />
63                            )}
64                        </button>
65                    </div>
66                </div>
67                <DialogFooter>
68                    <DialogClose asChild>
69                        <Button variant="outline">Close</Button>
70                    </DialogClose>
71                </DialogFooter>
72            </DialogContent>
73        </Dialog>
74    )
75}
76
Clipboard with dialog
clipboard-copy-09