Adds button to copy state to clipboard

This commit is contained in:
Steve Ruiz 2021-07-04 19:54:10 +01:00
parent 8180146eb3
commit a315f8e9a6
2 changed files with 46 additions and 32 deletions

View file

@ -7,8 +7,10 @@ import { breakpoints, IconButton, RowButton, IconWrapper } from '../shared'
import { import {
Cross2Icon, Cross2Icon,
PlayIcon, PlayIcon,
DotIcon,
CrumpledPaperIcon, CrumpledPaperIcon,
StopIcon, StopIcon,
ClipboardIcon,
ClipboardCopyIcon, ClipboardCopyIcon,
} from '@radix-ui/react-icons' } from '@radix-ui/react-icons'
import logger from 'state/logger' import logger from 'state/logger'
@ -16,6 +18,7 @@ import { useStateDesigner } from '@state-designer/react'
const stopPropagation = (e: React.KeyboardEvent) => e.stopPropagation() const stopPropagation = (e: React.KeyboardEvent) => e.stopPropagation()
const toggleDebugPanel = () => state.send('TOGGLED_DEBUG_PANEL') const toggleDebugPanel = () => state.send('TOGGLED_DEBUG_PANEL')
const handleStateCopy = () => state.send('COPIED_STATE_TO_CLIPBOARD')
export default function CodePanel(): JSX.Element { export default function CodePanel(): JSX.Element {
const rContainer = useRef<HTMLDivElement>(null) const rContainer = useRef<HTMLDivElement>(null)
@ -104,12 +107,19 @@ export default function CodePanel(): JSX.Element {
<div /> <div />
</Panel.Header> </Panel.Header>
<Panel.Content> <Panel.Content>
<hr />
<RowButton bp={breakpoints} onClick={handleStateCopy}>
<span>Copy State</span>
<IconWrapper size="small">
<ClipboardCopyIcon />
</IconWrapper>
</RowButton>
<hr /> <hr />
{local.isIn('stopped') ? ( {local.isIn('stopped') ? (
<RowButton bp={breakpoints} onClick={handleLoggingStart}> <RowButton bp={breakpoints} onClick={handleLoggingStart}>
<span>Start Logger</span> <span>Start Logger</span>
<IconWrapper size="small"> <IconWrapper size="small">
<PlayIcon /> <DotIcon />
</IconWrapper> </IconWrapper>
</RowButton> </RowButton>
) : ( ) : (
@ -120,19 +130,15 @@ export default function CodePanel(): JSX.Element {
</IconWrapper> </IconWrapper>
</RowButton> </RowButton>
)} )}
{ <JSONTextAreaWrapper>
<RowButton <IconButton
bp={breakpoints} bp={breakpoints}
onClick={handleLoggingCopy} onClick={handleLoggingCopy}
disabled={!local.can('COPIED_LOG')} disabled={!local.can('COPIED_LOG')}
style={{ position: 'absolute', top: 2, right: 2 }}
> >
<span>Copy Log</span> <ClipboardIcon />
<IconWrapper size="small"> </IconButton>
<ClipboardCopyIcon />
</IconWrapper>
</RowButton>
}
<JSONTextAreaWrapper>
<JSONTextArea <JSONTextArea
ref={rTextArea} ref={rTextArea}
value={local.data.log} value={local.data.log}
@ -147,6 +153,9 @@ export default function CodePanel(): JSX.Element {
disabled={!local.can('PLAYED_BACK_LOG')} disabled={!local.can('PLAYED_BACK_LOG')}
> >
<span>Play Back Log</span> <span>Play Back Log</span>
<IconWrapper size="small">
<PlayIcon />
</IconWrapper>
</RowButton> </RowButton>
</Panel.Content> </Panel.Content>
</Panel.Layout> </Panel.Layout>
@ -185,7 +194,8 @@ const StylePanelRoot = styled(Panel.Root, {
}) })
const JSONTextAreaWrapper = styled('div', { const JSONTextAreaWrapper = styled('div', {
padding: '4px', position: 'relative',
margin: '4px 0',
}) })
const JSONTextArea = styled('textarea', { const JSONTextArea = styled('textarea', {

View file

@ -119,30 +119,34 @@ class Clipboard {
} }
copyStringToClipboard = (string: string) => { copyStringToClipboard = (string: string) => {
const textarea = document.createElement('textarea')
textarea.setAttribute('position', 'fixed')
textarea.setAttribute('top', '0')
textarea.setAttribute('readonly', 'true')
textarea.setAttribute('contenteditable', 'true')
textarea.style.position = 'fixed'
textarea.value = string
document.body.appendChild(textarea)
textarea.focus()
textarea.select()
try { try {
const range = document.createRange() navigator.clipboard.writeText(string)
range.selectNodeContents(textarea) } catch (e) {
const textarea = document.createElement('textarea')
textarea.setAttribute('position', 'fixed')
textarea.setAttribute('top', '0')
textarea.setAttribute('readonly', 'true')
textarea.setAttribute('contenteditable', 'true')
textarea.style.position = 'fixed'
textarea.value = string
document.body.appendChild(textarea)
textarea.focus()
textarea.select()
const sel = window.getSelection() try {
sel.removeAllRanges() const range = document.createRange()
sel.addRange(range) range.selectNodeContents(textarea)
textarea.setSelectionRange(0, textarea.value.length) const sel = window.getSelection()
} catch (err) { sel.removeAllRanges()
null // Could not copy to clipboard sel.addRange(range)
} finally {
document.body.removeChild(textarea) textarea.setSelectionRange(0, textarea.value.length)
} catch (err) {
null // Could not copy to clipboard
} finally {
document.body.removeChild(textarea)
}
} }
return this return this