Skip to content

Commit 623fa6f

Browse files
chore(components): remove copy to clipboard utility method REL-10629 (#1815)
1 parent 1e97e24 commit 623fa6f

File tree

2 files changed

+7
-68
lines changed

2 files changed

+7
-68
lines changed

.changeset/rare-dancers-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@launchpad-ui/components": patch
3+
---
4+
5+
remove the copyToClipboard utility method

packages/components/src/utils.tsx

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import type { Href } from '@react-types/shared';
2-
import type { Context, ReactNode, Ref } from 'react';
2+
import type { Context, Ref } from 'react';
33
import type { ContextValue, SlotProps } from 'react-aria-components';
44

5-
import { announce } from '@react-aria/live-announcer';
65
import { mergeRefs } from '@react-aria/utils';
76
import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
87
import { mergeProps } from 'react-aria';
98
import { useSlottedContext } from 'react-aria-components';
109
import { useHref as useRouterHref } from 'react-router';
1110

12-
import { toastQueue } from './Toast';
13-
1411
type ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';
1512

1613
const useMedia = (media: string) => {
@@ -94,67 +91,4 @@ const useLPContextProps = <T, U extends SlotProps, E>(
9491
return [mergedProps, mergedRef];
9592
};
9693

97-
const fallbackCopyToClipboard = (text: string) =>
98-
new Promise<boolean>((resolve, reject) => {
99-
// Using setTimeout to ensure we focus the text area after the DOM is updated
100-
// in cases of dropdown menus
101-
setTimeout(() => {
102-
try {
103-
const textArea = document.createElement('textarea');
104-
textArea.value = text;
105-
106-
textArea.style.position = 'fixed';
107-
textArea.style.left = '-999999px';
108-
textArea.style.top = '-999999px';
109-
document.body.appendChild(textArea);
110-
111-
textArea.focus();
112-
textArea.select();
113-
114-
const successful = document.execCommand('copy');
115-
document.body.removeChild(textArea);
116-
117-
if (successful) {
118-
resolve(true);
119-
} else {
120-
reject(new Error('execCommand failed'));
121-
}
122-
} catch (error) {
123-
reject(error);
124-
}
125-
}, 10); // Small delay to ensure focus operations complete
126-
});
127-
128-
// navigator.clipboard is only available in secure contexts (https)
129-
// We need to use document.execCommand for insecure contexts (http)
130-
// for example when testing the Sandbox locally
131-
const copyToClipboard = async (
132-
text: string,
133-
toastMessage?: string | ReactNode,
134-
errorMessage?: string | ReactNode,
135-
) => {
136-
const MAX_WIDTH = 80;
137-
138-
try {
139-
if ('clipboard' in navigator) {
140-
await navigator.clipboard.writeText(text);
141-
} else {
142-
await fallbackCopyToClipboard(text);
143-
}
144-
145-
toastQueue.add({
146-
title:
147-
toastMessage ??
148-
`'${text.length > MAX_WIDTH ? `${text.slice(0, MAX_WIDTH)}...` : text}' copied to clipboard.`,
149-
status: 'success',
150-
});
151-
announce('Copied!', 'polite', 300);
152-
return true;
153-
} catch {
154-
announce('Failed to copy', 'polite', 300);
155-
toastQueue.add({ title: errorMessage ?? 'Unable to copy', status: 'error' });
156-
return false;
157-
}
158-
};
159-
160-
export { copyToClipboard, useHref, useImageLoadingStatus, useLPContextProps, useMedia };
94+
export { useHref, useImageLoadingStatus, useLPContextProps, useMedia };

0 commit comments

Comments
 (0)