{"version":3,"sources":["../../src/use-clipboard/index.ts"],"sourcesContent":["import { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { usePermission } from '../use-permission'\nimport { useStableFn } from '../use-stable-fn'\nimport { useSupported } from '../use-supported'\nimport { useTimeoutFn } from '../use-timeout-fn'\nimport { useTrackedRefState } from '../use-tracked-ref-state'\nimport { isDefined } from '../utils/basic'\nimport { unwrapGettable } from '../utils/unwrap'\nimport { legacyCopy, legacyRead } from './legacy'\n\nimport type { UsePermissionReturns } from '../use-permission'\nimport type { Gettable } from '../utils/basic'\n\nexport interface UseClipboardOptions<Source> {\n  /**\n   * Enabled reading for clipboard, need to request permission\n   *\n   * @defaultValue false\n   */\n  read?: boolean\n  /**\n   * Copy source, which is copied by default when you call the copy method directly without passing any parameters\n   */\n  source?: Source\n  /**\n   * Milliseconds to reset state of `copied` ref\n   *\n   * @defaultValue 1_500\n   */\n  copiedDuration?: number\n  /**\n   * Callback when the text is copied\n   */\n  onCopy?: (text: string) => void\n  /**\n   * Callback when the `copied` state is reset\n   */\n  onCopiedReset?: () => void\n}\n\nexport interface UseClipboardReturns<HasSource> {\n  /**\n   * Whether the Clipboard API is supported\n   */\n  isSupported: boolean\n  /**\n   * The text in the clipboard\n   */\n  text: string\n  /**\n   * A flag to indicate the text is copied, will be reset after `copiedDuration`\n   */\n  copied: boolean\n  /**\n   * Copy the text to the clipboard\n   */\n  copy: HasSource extends true ? (text?: string) => Promise<void> : (text: string) => Promise<void>\n  /**\n   * Clear the text in the clipboard\n   */\n  clear(): void\n}\n\n/**\n * A React Hook that copy text with [Clipboard API](https://developer.mozilla.org/zh-CN/docs/Web/API/Clipboard_API) or fallback to `document.execCommand('copy')` if it's not available.\n */\nexport function useClipboard(options?: UseClipboardOptions<undefined>): UseClipboardReturns<false>\nexport function useClipboard(options: UseClipboardOptions<Gettable<string>>): UseClipboardReturns<true>\nexport function useClipboard(\n  options: UseClipboardOptions<Gettable<string> | undefined> = {},\n): UseClipboardReturns<boolean> {\n  const { read = false, source, onCopy, onCopiedReset, copiedDuration = 1500 } = options\n\n  const [refState, actions] = useTrackedRefState({\n    text: '',\n    copied: false,\n  })\n\n  const isSupported = useSupported(() => 'clipboard' in navigator)\n\n  const { resume: startTimeout } = useTimeoutFn(() => {\n    actions.updateRefState('copied', false)\n    latest.current.onCopiedReset?.()\n  }, copiedDuration)\n\n  const latest = useLatest({\n    read,\n    onCopy,\n    onCopiedReset,\n    isSupported,\n    sourceValue: unwrapGettable(source),\n  })\n\n  const permissionRead = usePermission('clipboard-read', {\n    onStateChange() {\n      if (latest.current.read) updateText()\n    },\n  })\n\n  const permissionWrite = usePermission('clipboard-write')\n\n  const updateText = useStableFn(async () => {\n    if (latest.current.isSupported && isAllowed(permissionRead)) {\n      // to prevent error when document is not focused\n      // => Failed to execute 'readText' on 'Clipboard': Document is not focused.\n      if (document.hasFocus()) {\n        const value = await navigator.clipboard.readText()\n        actions.updateRefState('text', value)\n      }\n    } else {\n      actions.updateRefState('text', legacyRead())\n    }\n  })\n\n  const copy = useStableFn(async (value = latest.current.sourceValue) => {\n    if (!isDefined(value)) return\n\n    if (latest.current.isSupported && isAllowed(permissionWrite)) {\n      await navigator.clipboard.writeText(value)\n    } else {\n      legacyCopy(value)\n    }\n\n    actions.updateRefState('text', value)\n    actions.updateRefState('copied', true)\n    startTimeout()\n    latest.current.onCopy?.(value)\n  })\n\n  const clear = useStableFn(() => {\n    actions.updateRefState('text', '')\n    navigator.clipboard.writeText('')\n  })\n\n  useEventListener(isSupported && read ? ['copy', 'cut', 'focus'] : [], updateText)\n\n  return {\n    isSupported,\n    copy,\n    clear,\n    get text() {\n      return refState.text\n    },\n    get copied() {\n      return refState.copied\n    },\n  }\n}\n\nfunction isAllowed(status: UsePermissionReturns<false>) {\n  return status.current && ['granted', 'prompt'].includes(status.current)\n}\n"],"names":["useClipboard","options","read","source","onCopy","onCopiedReset","copiedDuration","useTrackedRefState","text","copied","refState","actions","isSupported","useSupported","navigator","useTimeoutFn","latest","updateRefState","current","resume","startTimeout","useLatest","sourceValue","unwrapGettable","permissionRead","usePermission","onStateChange","updateText","permissionWrite","useStableFn","value","isAllowed","document","hasFocus","clipboard","readText","legacyRead","copy","isDefined","writeText","legacyCopy","clear","useEventListener","status","includes"],"mappings":"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"}