/
kaws
/
ui-kit-ce
Обзор
Документация
Войти
/
kaws
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
packages/hooks/src/useCopy/useCopy.ts
152 строки
4 KB
zavyalov.d.o
docs: переделан функционал копирования через useCopy в компоненте Code
15 май 2025, 17:24
15 май 2025, 17:24
3cd5e32
Код
Авторство
О чём код?
'use client' import { useState, useRef, useEffect } from 'react' export type UseCopyProps = { /** * Текст, предназначенный для копирования в буфер обмена. * * @inner */ text?: string /** * Продолжительность показа состояния "скопировано" в миллисекундах. * * @inner */ copiedDuration?: number /** * Функция обратного вызова, срабатывающая в момент копирования текста. * * @param {string} text Копируемый текст. * * @returns */ onCopy?: (text: string) => void /** * Функция обратного вызова, срабатывающая перед копированием текста. * * @param {string} text Копируемый текст. * * @returns */ onBeforeCopy?: (text: string) => void /** * Функция обратного вызова, позволяющая изменить текст, копируемый в буфер обмена. * * @param {string} text Копируемый текст. * * @returns */ getCopyText?: (text: string) => string /** * Функция обратного вызова, отвечающая за обработку ошибки при копировании текста. * * @returns */ onError?: (error: Error) => void } export type UseCopyReturnProps = { /** * Состояние копирования. * * @inner */ isCopied: boolean /** * Функция обратного вызова, реализующая копирование текста в буфер обмена. * * @returns Обещание выполнения копирования в буфер обмена. */ copyToClipboard: () => Promise<void> } const copyToClipboardNonSecureContext = ( text: string, onError?: (error: Error) => void ) => { const textArea = document.createElement('textarea') textArea.value = text textArea.style.position = 'fixed' textArea.style.top = '-9999px' textArea.style.left = '-9999px' document.body.appendChild(textArea) textArea.focus() textArea.select() try { document.execCommand('copy') } catch (error) { if (onError) { onError(error as Error) } else { console.error(error) } } finally { textArea.remove() } } /** * Хук, предназначенный для копирования текста в буфер обмена. * * @param options Свойства для конфигурации хука. */ export const useCopy = ({ copiedDuration = 2000, onCopy, onBeforeCopy, getCopyText, text = '', onError, }: UseCopyProps): UseCopyReturnProps => { const [isCopied, setIsCopied] = useState(false) const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null) const handleCopySuccess = (finalText: string) => { if (copiedDuration > 0) { setIsCopied(true) timeoutRef.current = setTimeout(() => setIsCopied(false), copiedDuration) } onCopy?.(finalText) } const copyToClipboard = async () => { const finalText = getCopyText ? getCopyText(text) : text try { onBeforeCopy?.(finalText) if (!window.isSecureContext) { copyToClipboardNonSecureContext(finalText, onError) } else { await navigator.clipboard.writeText(finalText) } handleCopySuccess(finalText) } catch (error) { if (error instanceof Error) { if (onError) { onError(error) } else { console.error(error?.message) } } } } useEffect( () => () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) } }, [] ) return { isCopied, copyToClipboard, } }