use-copy-feedback.ts 1.1 KB

12345678910111213141516171819202122232425262728293031
  1. import { useCallback, useState } from 'react'
  2. import { writeClipboard } from './clipboard.ts'
  3. /** How long the `copied` flag stays true after a successful write, in ms. */
  4. const COPIED_FEEDBACK_MS = 1000
  5. /** The copy-feedback hook's return: the transient flag and the copy handler. */
  6. export interface CopyFeedback {
  7. /** True for {@link COPIED_FEEDBACK_MS} after a successful write; render the success label off it. */
  8. copied: boolean
  9. /** Copy the hook's text; no-op while `copied` is still true, silent on a refused write. */
  10. onCopy: () => void
  11. }
  12. /**
  13. * Copy `text` to the clipboard with one-second success feedback.
  14. * @param text - the text to write on copy.
  15. * @returns the `copied` flag and the `onCopy` handler.
  16. */
  17. export function useCopyFeedback(text: string): CopyFeedback {
  18. const [copied, setCopied] = useState(false)
  19. const onCopy = useCallback(() => {
  20. if (copied) return
  21. void writeClipboard(text).then((ok) => {
  22. if (!ok) return
  23. setCopied(true)
  24. window.setTimeout(() => { setCopied(false) }, COPIED_FEEDBACK_MS)
  25. })
  26. }, [copied, text])
  27. return { copied, onCopy }
  28. }