/
githubmirror
/
carbon
Обзор
Документация
Войти
/
githubmirror
/
carbon
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/CopyMenu.js
144 строки
4 KB
hatsu
Responsive for mobile (#1331)
08 фев 2022, 05:25
Не верифицирован
08 фев 2022, 05:25
3da8262
Код
Авторство
О чём код?
import React from 'react' import { useRouter } from 'next/router' import { useCopyTextHandler, useAsyncCallback, useKeyboardListener } from 'actionsack' import morph from 'morphmorph' import { COLORS } from '../lib/constants' import Button from './Button' import Popout, { managePopout } from './Popout' import CopySVG from './svg/Copy' const toIFrame = (url, width, height) => `<iframe src="${location.origin}/embed${url.replace(/^\/\?/, '?')}" style="width: ${width || 1024}px; height: ${ height || 473 }px; border:0; transform: scale(1); overflow:hidden;" sandbox="allow-scripts allow-same-origin"> </iframe> ` const toURL = url => `${location.origin}${url}` // Medium does not handle asterisks correctly - https://github.com/carbon-app/carbon/issues/1067 const replaceAsterisks = string => string.replace(/\*/g, '%2A') const toEncodedURL = morph.compose(encodeURI, replaceAsterisks, toURL) function CopyButton(props) { return ( <Button {...props} hoverColor={COLORS.SECONDARY} color="rgba(255, 255, 255, 0.7)" padding="8px" /> ) } function CopyEmbed({ mapper, title }) { const { asPath } = useRouter() const text = React.useMemo(() => mapper(asPath), [mapper, asPath]) const { onClick, copied } = useCopyTextHandler(text) return <CopyButton onClick={onClick}>{copied ? 'Copied!' : title}</CopyButton> } const popoutStyle = { width: '140px', right: 0 } function useClipboardSupport() { const [isClipboardSupported, setClipboardSupport] = React.useState(false) React.useEffect(() => { setClipboardSupport( window.navigator && window.navigator.clipboard && typeof ClipboardItem === 'function' ) }, []) return isClipboardSupported } function CopyMenu({ isVisible, toggleVisibility, copyImage, carbonRef }) { const clipboardSupported = useClipboardSupport() const [showCopied, { loading: copied }] = useAsyncCallback( () => new Promise(res => setTimeout(res, 1000)) ) const [copy, { loading }] = useAsyncCallback(async (...args) => { if (clipboardSupported) { await copyImage(...args) showCopied() } }) useKeyboardListener('⌘-⇧-c', e => { e.preventDefault() copy(e) }) return ( <div className="copy-menu-container"> <div className="flex"> <Button center border large padding="0 16px" margin="0 8px 0 0" onClick={toggleVisibility} color={COLORS.SECONDARY} title="Copy menu" > <CopySVG size={16} color={COLORS.SECONDARY} /> </Button> </div> <Popout hidden={!isVisible} borderColor={COLORS.SECONDARY} pointerRight="24px" style={popoutStyle} > <div className="copy-row flex"> <span>Copy to clipboard</span> {clipboardSupported && ( <CopyButton id="export-clipboard" onClick={copy} disabled={loading}> {loading ? 'Copying…' : copied ? 'Copied!' : 'Image'} </CopyButton> )} <CopyEmbed title="Medium.com" mapper={toEncodedURL} /> <CopyEmbed title="IFrame" mapper={url => toIFrame(url, carbonRef.clientWidth, carbonRef.clientHeight)} /> <CopyEmbed title="Plain URL" mapper={toURL} /> </div> </Popout> <style jsx> {` .copy-menu-container { position: relative; color: ${COLORS.SECONDARY}; flex: 1; max-width: 40px; } .copy-row { flex-direction: column; justify-content: space-between; border-bottom: 1px solid ${COLORS.SECONDARY}; } .copy-row :global(button) { border-top: 1px solid ${COLORS.SECONDARY}; } .copy-row > span { padding: 8px; margin: 0 auto; } `} </style> </div> ) } export default managePopout(React.memo(CopyMenu))