Skip to content

Commit 244abb2

Browse files
authored
Merge pull request dubinc#2270 from dubinc/add-copy-btn
Add copy to clipboard on the links page
2 parents fd62570 + 1b17f6a commit 244abb2

2 files changed

Lines changed: 42 additions & 3 deletions

File tree

apps/web/app/app.dub.co/(dashboard)/[slug]/links/[...link]/page-client.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,19 @@ import { TagSelect } from "@/ui/links/link-builder/tag-select";
2626
import { useLinkBuilderSubmit } from "@/ui/links/link-builder/use-link-builder-submit";
2727
import { useMetatags } from "@/ui/links/link-builder/use-metatags";
2828
import { LinkControls } from "@/ui/links/link-controls";
29-
import { useKeyboardShortcut, useMediaQuery } from "@dub/ui";
29+
import {
30+
Button,
31+
Check,
32+
Copy,
33+
useCopyToClipboard,
34+
useKeyboardShortcut,
35+
useMediaQuery,
36+
} from "@dub/ui";
3037
import { cn } from "@dub/utils";
3138
import { notFound, useParams, useRouter } from "next/navigation";
3239
import { memo, useEffect, useRef, useState } from "react";
3340
import { useFormContext, useFormState } from "react-hook-form";
41+
import { toast } from "sonner";
3442

3543
export function LinkPageClient() {
3644
const params = useParams<{ link: string | string[] }>();
@@ -78,7 +86,8 @@ function LinkBuilder({ link }: { link: ExpandedLinkProps }) {
7886
const router = useRouter();
7987
const workspace = useWorkspace();
8088

81-
const { isDesktop } = useMediaQuery();
89+
const { isDesktop, isMobile } = useMediaQuery();
90+
const [copied, copyToClipboard] = useCopyToClipboard();
8291

8392
const { control, handleSubmit, reset, getValues } =
8493
useFormContext<LinkFormData>();
@@ -152,6 +161,36 @@ function LinkBuilder({ link }: { link: ExpandedLinkProps }) {
152161
props={link}
153162
workspaceId={workspace.id!}
154163
/>
164+
<Button
165+
icon={
166+
<div className="relative size-4">
167+
<div
168+
className={cn(
169+
"absolute inset-0 transition-[transform,opacity]",
170+
copied && "translate-y-1 opacity-0",
171+
)}
172+
>
173+
<Copy className="size-4" />
174+
</div>
175+
<div
176+
className={cn(
177+
"absolute inset-0 transition-[transform,opacity]",
178+
!copied && "translate-y-1 opacity-0",
179+
)}
180+
>
181+
<Check className="size-4" />
182+
</div>
183+
</div>
184+
}
185+
text="Copy link"
186+
variant="secondary"
187+
className="xs:w-fit h-7 px-2.5"
188+
onClick={() => {
189+
copyToClipboard(link.shortLink).then(() => {
190+
toast.success("Link copied to clipboard");
191+
});
192+
}}
193+
/>
155194
<div className="shrink-0">
156195
<LinkAnalyticsBadge link={link} />
157196
</div>

apps/web/ui/links/link-builder/draft-controls.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export const DraftControls = forwardRef<
148148
type="button"
149149
variant="outline"
150150
className={cn(
151-
"animate-fade-in group h-9 w-fit text-sm transition-colors data-[state=open]:bg-neutral-100",
151+
"animate-fade-in group h-7 w-fit text-sm transition-colors data-[state=open]:bg-neutral-100",
152152
isDirty && hasSaved
153153
? "pl-3 pr-4 text-neutral-400 hover:text-neutral-600"
154154
: "pl-4 pr-3 text-neutral-500 hover:text-neutral-700",

0 commit comments

Comments
 (0)