@@ -7,24 +7,35 @@ interface UseCopyToClipboardOptions {
77 resetMs ?: number
88}
99
10+ export interface DeferredClipboardContent {
11+ /** Safe text that can be written immediately when promise-backed writes are unavailable. */
12+ fallback : string
13+ /** Produces the preferred text when the browser supports promise-backed clipboard items. */
14+ prepare : ( ) => Promise < string >
15+ }
16+
17+ export type ClipboardContent = string | DeferredClipboardContent
18+
1019interface UseCopyToClipboardReturn {
1120 copied : boolean
12- copy : ( text : string | Promise < string > ) => Promise < boolean >
21+ copy : ( content : ClipboardContent ) => Promise < boolean >
1322}
1423
1524/**
1625 * Starts an async clipboard write while the caller still has transient user activation.
17- * Promise-backed text uses `ClipboardItem` so preparation can finish after the write begins .
26+ * Deferred text uses `ClipboardItem` when available and an immediate fallback otherwise .
1827 */
19- export function writeTextToClipboard ( text : string | Promise < string > ) : Promise < void > {
20- if ( typeof text === 'string' ) return navigator . clipboard . writeText ( text )
28+ export function writeTextToClipboard ( content : ClipboardContent ) : Promise < void > {
29+ if ( typeof content === 'string' ) return navigator . clipboard . writeText ( content )
2130
2231 if ( typeof ClipboardItem !== 'undefined' && typeof navigator . clipboard . write === 'function' ) {
23- const blob = text . then ( ( value ) => new Blob ( [ value ] , { type : 'text/plain' } ) )
32+ const blob = Promise . resolve ( )
33+ . then ( ( ) => content . prepare ( ) )
34+ . then ( ( value ) => new Blob ( [ value ] , { type : 'text/plain' } ) )
2435 return navigator . clipboard . write ( [ new ClipboardItem ( { 'text/plain' : blob } ) ] )
2536 }
2637
27- return text . then ( ( value ) => navigator . clipboard . writeText ( value ) )
38+ return navigator . clipboard . writeText ( content . fallback )
2839}
2940
3041/**
@@ -49,9 +60,9 @@ export function useCopyToClipboard(
4960 const timerRef = useRef < ReturnType < typeof setTimeout > | null > ( null )
5061
5162 const copy = useCallback (
52- async ( text : string | Promise < string > ) : Promise < boolean > => {
63+ async ( content : ClipboardContent ) : Promise < boolean > => {
5364 try {
54- await writeTextToClipboard ( text )
65+ await writeTextToClipboard ( content )
5566 setCopied ( true )
5667 if ( timerRef . current ) clearTimeout ( timerRef . current )
5768 timerRef . current = setTimeout ( ( ) => setCopied ( false ) , resetMs )
0 commit comments