asb_cloud_front/src/components/CopyUrl.tsx

56 lines
1.9 KiB
TypeScript
Raw Normal View History

import { cloneElement, memo, useCallback, useMemo, useState } from 'react'
import { Button, ButtonProps } from 'antd'
import { CopyOutlined } from '@ant-design/icons'
import { invokeWebApiWrapperAsync, notify } from './factory'
export type CopyUrlProps = {
sendLoading?: boolean
hideUnsupported?: boolean
onCopy?: () => (void | Promise<void>)
children: JSX.Element
}
export const CopyUrl = memo<CopyUrlProps>(({ children, onCopy, sendLoading, hideUnsupported = true }) => {
const props = useMemo(() => children.props, [children])
const [loading, setLoading] = useState(false)
const supported = !!navigator?.clipboard?.writeText // Проверка поддержки
const onClick = useCallback((event: MouseEvent) => {
if (supported) {
invokeWebApiWrapperAsync(
async () => {
await navigator.clipboard.writeText(window.location.href)
await onCopy?.()
notify('URL успешно скопирован', 'info')
},
setLoading,
`Не удалось скопировать URL в буфер обмена`
)
}
props.onClick?.(event) // Запуск onClick по-умолчанию
}, [props])
if (hideUnsupported && !supported) return null
return cloneElement(children, { onClick, loading: sendLoading ? loading : props.loading })
})
export type CopyUrlButtonProps = Omit<CopyUrlProps, 'children'> & ButtonProps
export const CopyUrlButton = memo<CopyUrlButtonProps>(({ sendLoading, hideUnsupported, onCopy, ...other }) => {
return (
<CopyUrl sendLoading={sendLoading} hideUnsupported={hideUnsupported} onCopy={onCopy}>
<Button
icon={<CopyOutlined />}
title={'Скопировать URL в буфер обмена'}
{...other}
/>
</CopyUrl>
)
})
export default CopyUrl