From 7f1277e2f6259827747a4827e9bc73e910271617 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 8 Dec 2023 16:21:02 -0800 Subject: [PATCH 1/5] Extract CopyToClipboard to own component --- app/components/CopyToClipboard.tsx | 35 +++++++++++++++++++ .../instances/instance/tabs/NetworkingTab.tsx | 14 +++++++- libs/ui/lib/truncate/Truncate.tsx | 27 ++------------ 3 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 app/components/CopyToClipboard.tsx diff --git a/app/components/CopyToClipboard.tsx b/app/components/CopyToClipboard.tsx new file mode 100644 index 0000000000..f7b71ea48f --- /dev/null +++ b/app/components/CopyToClipboard.tsx @@ -0,0 +1,35 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright Oxide Computer Company + */ + +import { useState } from 'react' + +import { Clipboard16Icon, Success12Icon, useTimeout } from '@oxide/ui' + +export const CopyToClipboard = ({ text }: { text: string }) => { + const [hasCopied, setHasCopied] = useState(false) + + useTimeout(() => setHasCopied(false), hasCopied ? 2000 : null) + + const handleCopy = () => { + window.navigator.clipboard.writeText(text).then(() => { + setHasCopied(true) + }) + } + + return hasCopied ? ( + + ) : ( + + ) +} diff --git a/app/pages/project/instances/instance/tabs/NetworkingTab.tsx b/app/pages/project/instances/instance/tabs/NetworkingTab.tsx index 218502e1a4..e0a6886216 100644 --- a/app/pages/project/instances/instance/tabs/NetworkingTab.tsx +++ b/app/pages/project/instances/instance/tabs/NetworkingTab.tsx @@ -27,6 +27,7 @@ import { Success12Icon, } from '@oxide/ui' +import { CopyToClipboard } from 'app/components/CopyToClipboard' import CreateNetworkInterfaceForm from 'app/forms/network-interface-create' import EditNetworkInterfaceForm from 'app/forms/network-interface-edit' import { @@ -84,7 +85,18 @@ function ExternalIpsFromInstanceName({ value: primary }: { value: boolean }) { query: { project }, }) const ips = data?.items.map((eip) => eip.ip).join(', ') - return {primary ? ips : <>—} + return ( +
+ {primary ? ( + <> + {ips} + + + ) : ( + <>— + )} +
+ ) } NetworkingTab.loader = async ({ params }: LoaderFunctionArgs) => { diff --git a/libs/ui/lib/truncate/Truncate.tsx b/libs/ui/lib/truncate/Truncate.tsx index 3764c1634f..ea8a8b25bb 100644 --- a/libs/ui/lib/truncate/Truncate.tsx +++ b/libs/ui/lib/truncate/Truncate.tsx @@ -5,11 +5,9 @@ * * Copyright Oxide Computer Company */ -import { useState } from 'react' -import { Clipboard16Icon, Success12Icon } from '@oxide/design-system/icons/react' +import { CopyToClipboard } from 'app/components/CopyToClipboard' -import useTimeout from '../hooks/use-timeout' import { Tooltip } from '../tooltip/Tooltip' type TruncatePosition = 'middle' | 'end' @@ -29,38 +27,17 @@ export const Truncate = ({ hasCopyButton, tooltipDelay = 300, }: TruncateProps) => { - const [hasCopied, setHasCopied] = useState(false) - - useTimeout(() => setHasCopied(false), hasCopied ? 2000 : null) - if (text.length <= maxLength) { return
{text}
} - const handleCopy = () => { - window.navigator.clipboard.writeText(text).then(() => { - setHasCopied(true) - }) - } - // Only use the tooltip if the text is longer than maxLength return (
{truncate(text, maxLength, position)}
- {hasCopyButton && - (hasCopied ? ( - - ) : ( - - ))} + {hasCopyButton && }
) } From 3a7d7ce7643f325a74f054ff4eea74117f7add8d Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 8 Dec 2023 16:30:46 -0800 Subject: [PATCH 2/5] Back out changes on NetworkingTab for now --- .../instances/instance/tabs/NetworkingTab.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/app/pages/project/instances/instance/tabs/NetworkingTab.tsx b/app/pages/project/instances/instance/tabs/NetworkingTab.tsx index e0a6886216..218502e1a4 100644 --- a/app/pages/project/instances/instance/tabs/NetworkingTab.tsx +++ b/app/pages/project/instances/instance/tabs/NetworkingTab.tsx @@ -27,7 +27,6 @@ import { Success12Icon, } from '@oxide/ui' -import { CopyToClipboard } from 'app/components/CopyToClipboard' import CreateNetworkInterfaceForm from 'app/forms/network-interface-create' import EditNetworkInterfaceForm from 'app/forms/network-interface-edit' import { @@ -85,18 +84,7 @@ function ExternalIpsFromInstanceName({ value: primary }: { value: boolean }) { query: { project }, }) const ips = data?.items.map((eip) => eip.ip).join(', ') - return ( -
- {primary ? ( - <> - {ips} - - - ) : ( - <>— - )} -
- ) + return {primary ? ips : <>—} } NetworkingTab.loader = async ({ params }: LoaderFunctionArgs) => { From 763bcfde83482116cbdea579735cf6909b69dbb3 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 8 Dec 2023 16:47:30 -0800 Subject: [PATCH 3/5] Add story for ladle --- .../CopyToClipboard.stories.tsx | 21 +++++++++++++++++++ .../lib/copyToClipboard}/CopyToClipboard.tsx | 0 libs/ui/lib/truncate/Truncate.tsx | 3 +-- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx rename {app/components => libs/ui/lib/copyToClipboard}/CopyToClipboard.tsx (100%) diff --git a/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx b/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx new file mode 100644 index 0000000000..826931a75a --- /dev/null +++ b/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx @@ -0,0 +1,21 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright Oxide Computer Company + */ +import { CopyToClipboard } from './CopyToClipboard' + +export const Default = () => ( +
+
+ This is the text to be copied. + +
+
+ Though you can copy whatever you like … + +
+
+) diff --git a/app/components/CopyToClipboard.tsx b/libs/ui/lib/copyToClipboard/CopyToClipboard.tsx similarity index 100% rename from app/components/CopyToClipboard.tsx rename to libs/ui/lib/copyToClipboard/CopyToClipboard.tsx diff --git a/libs/ui/lib/truncate/Truncate.tsx b/libs/ui/lib/truncate/Truncate.tsx index ea8a8b25bb..087880edb6 100644 --- a/libs/ui/lib/truncate/Truncate.tsx +++ b/libs/ui/lib/truncate/Truncate.tsx @@ -6,8 +6,7 @@ * Copyright Oxide Computer Company */ -import { CopyToClipboard } from 'app/components/CopyToClipboard' - +import { CopyToClipboard } from '../copyToClipboard/CopyToClipboard' import { Tooltip } from '../tooltip/Tooltip' type TruncatePosition = 'middle' | 'end' From 8d291cdb653e2cc7116973839d7faf702141498b Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Mon, 11 Dec 2023 10:50:26 -0800 Subject: [PATCH 4/5] Update aria-label for better screenreader support --- .../CopyToClipboard.stories.tsx | 11 +++++++++-- .../lib/copyToClipboard/CopyToClipboard.tsx | 19 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx b/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx index 826931a75a..544d6aeec6 100644 --- a/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx +++ b/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx @@ -13,9 +13,16 @@ export const Default = () => ( This is the text to be copied. +

+ Note that the text rendered on the screen is independent of the text copied to the + clipboard … +

- Though you can copy whatever you like … - + This text, for example, is different from the text that’ll be copied … +
) diff --git a/libs/ui/lib/copyToClipboard/CopyToClipboard.tsx b/libs/ui/lib/copyToClipboard/CopyToClipboard.tsx index f7b71ea48f..c521346eaf 100644 --- a/libs/ui/lib/copyToClipboard/CopyToClipboard.tsx +++ b/libs/ui/lib/copyToClipboard/CopyToClipboard.tsx @@ -10,7 +10,13 @@ import { useState } from 'react' import { Clipboard16Icon, Success12Icon, useTimeout } from '@oxide/ui' -export const CopyToClipboard = ({ text }: { text: string }) => { +export const CopyToClipboard = ({ + ariaLabel = 'Click to copy this text', + text, +}: { + ariaLabel?: string + text: string +}) => { const [hasCopied, setHasCopied] = useState(false) useTimeout(() => setHasCopied(false), hasCopied ? 2000 : null) @@ -21,15 +27,18 @@ export const CopyToClipboard = ({ text }: { text: string }) => { }) } - return hasCopied ? ( - - ) : ( + return ( ) } From b752f4d6eca9d3c481e5e36e2feeb51feecf71e3 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 13 Dec 2023 09:08:44 -0800 Subject: [PATCH 5/5] Update directory name to follow kebab-case-convention --- libs/ui/index.ts | 1 + .../CopyToClipboard.stories.tsx | 0 .../{copyToClipboard => copy-to-clipboard}/CopyToClipboard.tsx | 0 libs/ui/lib/truncate/Truncate.tsx | 2 +- 4 files changed, 2 insertions(+), 1 deletion(-) rename libs/ui/lib/{copyToClipboard => copy-to-clipboard}/CopyToClipboard.stories.tsx (100%) rename libs/ui/lib/{copyToClipboard => copy-to-clipboard}/CopyToClipboard.tsx (100%) diff --git a/libs/ui/index.ts b/libs/ui/index.ts index 19e4235329..e70fb970a0 100644 --- a/libs/ui/index.ts +++ b/libs/ui/index.ts @@ -18,6 +18,7 @@ export * from './lib/avatar/Avatar' export * from './lib/badge/Badge' export * from './lib/button/Button' export * from './lib/checkbox/Checkbox' +export * from './lib/copy-to-clipboard/CopyToClipboard' export * from './lib/date-picker/DateRangePicker' export * from './lib/divider/Divider' export * from './lib/dropdown-menu/DropdownMenu' diff --git a/libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx b/libs/ui/lib/copy-to-clipboard/CopyToClipboard.stories.tsx similarity index 100% rename from libs/ui/lib/copyToClipboard/CopyToClipboard.stories.tsx rename to libs/ui/lib/copy-to-clipboard/CopyToClipboard.stories.tsx diff --git a/libs/ui/lib/copyToClipboard/CopyToClipboard.tsx b/libs/ui/lib/copy-to-clipboard/CopyToClipboard.tsx similarity index 100% rename from libs/ui/lib/copyToClipboard/CopyToClipboard.tsx rename to libs/ui/lib/copy-to-clipboard/CopyToClipboard.tsx diff --git a/libs/ui/lib/truncate/Truncate.tsx b/libs/ui/lib/truncate/Truncate.tsx index 087880edb6..6bc0c65cda 100644 --- a/libs/ui/lib/truncate/Truncate.tsx +++ b/libs/ui/lib/truncate/Truncate.tsx @@ -6,7 +6,7 @@ * Copyright Oxide Computer Company */ -import { CopyToClipboard } from '../copyToClipboard/CopyToClipboard' +import { CopyToClipboard } from '../copy-to-clipboard/CopyToClipboard' import { Tooltip } from '../tooltip/Tooltip' type TruncatePosition = 'middle' | 'end'