Skip to content

Commit

Permalink
wallet-ext: copy to clipboard use toast for confirmation feedback
Browse files Browse the repository at this point in the history
* show a toast instead of scaling the copy icon
* move copy to functionality to hooks to reuse it
* also removes unused code for rendering sui objects
  • Loading branch information
pchrysochoidis committed Jan 27, 2023
1 parent 778c98c commit c84fb26
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 268 deletions.
6 changes: 5 additions & 1 deletion apps/wallet/src/ui/app/components/account-address/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ function AccountAddress({
return address ? (
<span className={cl(st.addressContainer, className)}>
{copyable ? (
<CopyToClipboard txt={address} mode={cpIconMode}>
<CopyToClipboard
txt={address}
mode={cpIconMode}
copySuccessMessage="Address copied"
>
{addressLink}
</CopyToClipboard>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,4 @@
&.plain {
font-weight: 100;
}

&.copied {
transform: scale(150%, 150%);
color: colors.$sui-blue;
opacity: 1;

&.plain {
color: inherit;
}
}
}
40 changes: 7 additions & 33 deletions apps/wallet/src/ui/app/components/copy-to-clipboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
// SPDX-License-Identifier: Apache-2.0

import cl from 'classnames';
import { memo, useCallback, useEffect, useState } from 'react';

import { useCopyToClipboard } from '../../hooks/useCopyToClipboard';
import Icon, { SuiIcons } from '_components/icon';

import type { ReactNode, MouseEventHandler } from 'react';
import type { ReactNode } from 'react';

import st from './CopyToClipboard.module.scss';

const COPY_CHECKMARK_MILLIS = 600;

export type CopyToClipboardProps = {
txt: string;
children: ReactNode;
copyOnlyOnIconClick?: boolean;
className?: string;
mode?: 'normal' | 'highlighted' | 'plain';
copySuccessMessage?: string;
};

function CopyToClipboard({
Expand All @@ -26,42 +25,17 @@ function CopyToClipboard({
copyOnlyOnIconClick = false,
className,
mode = 'normal',
copySuccessMessage,
}: CopyToClipboardProps) {
const [copied, setCopied] = useState(false);
const copyToClipboard = useCallback<MouseEventHandler<HTMLElement>>(
async (e) => {
e.stopPropagation();
e.preventDefault();
if (!txt) {
return;
}
await navigator.clipboard.writeText(txt);
setCopied(true);
},
[txt]
);
useEffect(() => {
let timeout: number;
if (copied) {
timeout = window.setTimeout(
() => setCopied(false),
COPY_CHECKMARK_MILLIS
);
}
return () => {
if (timeout) {
clearTimeout(timeout);
}
};
}, [copied]);
const copyToClipboard = useCopyToClipboard(txt, { copySuccessMessage });
return (
<span
className={cl(st.container, className)}
onClick={!copyOnlyOnIconClick ? copyToClipboard : undefined}
>
{children}
<Icon
className={cl(st.copyIcon, st[mode], { [st.copied]: copied })}
className={cl(st.copyIcon, st[mode])}
icon={SuiIcons.Copy}
onClick={copyToClipboard}
title="Copy to clipboard"
Expand All @@ -70,4 +44,4 @@ function CopyToClipboard({
);
}

export default memo(CopyToClipboard);
export default CopyToClipboard;
90 changes: 0 additions & 90 deletions apps/wallet/src/ui/app/components/sui-object/SuiObject.module.scss

This file was deleted.

This file was deleted.

24 changes: 0 additions & 24 deletions apps/wallet/src/ui/app/components/sui-object/field/index.tsx

This file was deleted.

94 changes: 0 additions & 94 deletions apps/wallet/src/ui/app/components/sui-object/index.tsx

This file was deleted.

28 changes: 28 additions & 0 deletions apps/wallet/src/ui/app/hooks/useCopyToClipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { type MouseEventHandler, useCallback } from 'react';
import { toast } from 'react-hot-toast';

export type CopyOptions = {
copySuccessMessage?: string;
};

export function useCopyToClipboard(
textToCopy: string,
{ copySuccessMessage = 'Copied' }: CopyOptions = {}
) {
return useCallback<MouseEventHandler>(
async (e) => {
e.stopPropagation();
e.preventDefault();
try {
await navigator.clipboard.writeText(textToCopy);
toast.success(copySuccessMessage);
} catch (e) {
// silence clipboard errors
}
},
[textToCopy, copySuccessMessage]
);
}

0 comments on commit c84fb26

Please sign in to comment.