fix(playground): fix arrow icon does not work correctly on webkit

This commit is contained in:
unix
2020-05-04 23:55:45 +08:00
parent c5f4c0811f
commit d73f5ef8f4
2 changed files with 147 additions and 135 deletions

View File

@@ -0,0 +1,128 @@
import React, { useState } from 'react'
import { LiveEditor } from 'react-live'
import { useConfigs } from 'lib/config-context'
import { useTheme, useToasts, Row, Col, Utils } from 'components'
import CopyIcon from '@zeit-ui/react-icons/copy'
import RightIcon from '@zeit-ui/react-icons/chevronRight'
const { useClipboard } = Utils
interface Props {
code: string
}
const Editor: React.FC<Props> = ({ code }) => {
const theme = useTheme()
const { copy } = useClipboard()
const { isChinese } = useConfigs()
const [visible, setVisible] = useState(false)
const [, setToast] = useToasts()
const clickHandler = (event: React.MouseEvent) => {
event.stopPropagation()
event.preventDefault()
setVisible(!visible)
}
const copyHandler = (event: React.MouseEvent) => {
event.stopPropagation()
event.preventDefault()
copy(code)
setToast({ text: isChinese ? '代码已拷贝至剪切板。' : 'code copied.' })
}
return (
<div className="editor">
<details open={visible}>
<summary onClick={clickHandler}>
<Row justify="space-between" align="middle" style={{ height: '100%', width: '100%' }}>
<Col className="action">
<span className="arrow"><RightIcon size={16} /></span>
<span>{isChinese ? '编辑代码' : 'Code Editor'}</span>
</Col>
<Col className="action">
{visible && (
<span className="copy" onClick={copyHandler} title={isChinese ? '拷贝代码' : 'Copy Code'}>
<CopyIcon size={18} />
</span>
)}
</Col>
</Row>
</summary>
<div className="area"><LiveEditor /></div>
</details>
<style jsx>{`
.editor {
border-bottom-left-radius: ${theme.layout.radius};
border-bottom-right-radius: ${theme.layout.radius};
}
details {
transition: all 0.2s ease;
overflow: hidden;
border-bottom-left-radius: ${theme.layout.radius};
border-bottom-right-radius: ${theme.layout.radius};
}
summary {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 ${theme.layout.gap};
border-top: 1px solid ${theme.palette.accents_2};
color: ${theme.palette.accents_5};
height: 2.875rem;
list-style: none;
user-select: none;
outline: none;
}
summary :global(svg) {
cursor: pointer;
}
summary :global(.action) {
width: auto;
display: flex;
align-items: center;
font-size: .8rem;
}
.area {
position: relative;
box-sizing: border-box;
white-space: pre;
font-family: ${theme.font.mono};
color: ${theme.palette.foreground};
background-color: ${theme.palette.background};
font-size: 1em;
overflow: hidden;
border-top: 1px solid ${theme.palette.accents_2};
padding: ${theme.layout.gapHalf};
}
.arrow {
transition: all .2s ease;
transform: rotate(${visible ? 90 : 0}deg);
display: inline-flex;
align-items: center;
width: 1rem;
height: 1rem;
margin-right: .5rem;
}
.copy {
display: inline-flex;
align-items: center;
color: ${theme.palette.accents_4};
transition: color .2s ease;
}
.copy:hover {
color: ${theme.palette.accents_6};
}
`}</style>
</div>
)
}
export default Editor

View File

@@ -1,12 +1,10 @@
import React, { useState } from 'react'
import { LivePreview, LiveProvider, LiveEditor, LiveError } from 'react-live'
import React from 'react'
import { useTheme } from 'components'
import withDefaults from 'components/utils/with-defaults'
import useClipboard from 'components/utils/use-clipboard'
import { useTheme, useToasts } from 'components'
import { LivePreview, LiveProvider, LiveError } from 'react-live'
import { useConfigs } from 'lib/config-context'
import makeCodeTheme from './code-theme'
import RightIcon from '@zeit-ui/react-icons/chevronRight'
import CopyIcon from '@zeit-ui/react-icons/copy'
import Editor from './editor'
import Title from './title'
interface Props {
@@ -26,126 +24,12 @@ const defaultProps = {
export type PlaygroundProps = Props & typeof defaultProps
const editor = (code: string, copy: Function, isChinese: boolean) => {
const theme = useTheme()
const [visible, setVisible] = useState(false)
const [, setToast] = useToasts()
const clickHandler = (event: React.MouseEvent) => {
event.stopPropagation()
event.preventDefault()
setVisible(!visible)
}
const copyHandler = (event: React.MouseEvent) => {
event.stopPropagation()
event.preventDefault()
copy(code)
setToast({ text: isChinese ? '代码已拷贝至剪切板。' : 'code copied.' })
}
return (
<div className="editor">
<details open={visible}>
<summary onClick={clickHandler}>
<div>
<span className="right-icon">
<RightIcon size={16} />
</span>
<span>{isChinese ? '编辑代码' : 'Code Editor'}</span>
</div>
<div>
{visible && (
<span className="copy" onClick={copyHandler} title={isChinese ? '拷贝代码' : 'Copy Code'}>
<CopyIcon size={18} />
</span>
)}
</div>
</summary>
<div className="area">
<LiveEditor />
</div>
</details>
<style jsx>{`
.editor {
border-bottom-left-radius: ${theme.layout.radius};
border-bottom-right-radius: ${theme.layout.radius};
}
details {
transition: all 0.2s ease;
overflow: hidden;
}
summary {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 ${theme.layout.gapHalf};
border-top: 1px solid ${theme.palette.accents_2};
color: ${theme.palette.accents_5};
height: 2.875rem;
list-style: none;
user-select: none;
outline: none;
}
summary > div {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: fit-content;
}
summary :global(svg) {
margin: 0 ${theme.layout.gapHalf};
cursor: pointer;
}
.area {
position: relative;
box-sizing: border-box;
white-space: pre;
font-family: ${theme.font.mono};
color: ${theme.palette.foreground};
background-color: ${theme.palette.background};
font-size: 1em;
overflow: hidden;
border-top: 1px solid ${theme.palette.accents_2};
padding: ${theme.layout.gapHalf};
}
.right-icon {
transition: all .2s ease;
transform: rotate(${visible ? 90 : 0}deg);
display: inline-flex;
align-items: center;
}
.copy {
display: inline-flex;
align-items: center;
color: ${theme.palette.accents_4};
transition: color .2s ease;
}
.copy:hover {
color: ${theme.palette.accents_6};
}
`}</style>
</div>
)
}
const Playground: React.FC<PlaygroundProps> = React.memo(({
title: inputTitle, code: inputCode, desc, scope,
}) => {
const theme = useTheme()
const { isChinese } = useConfigs()
const codeTheme = makeCodeTheme(theme)
const { copy } = useClipboard()
const code = inputCode.trim()
const title = inputTitle || (isChinese ? '基础的' : 'Default')
@@ -158,24 +42,24 @@ const Playground: React.FC<PlaygroundProps> = React.memo(({
<LivePreview />
<LiveError />
</div>
{editor(code, copy, !!isChinese)}
<Editor code={code} />
</LiveProvider>
<style jsx>{`
.playground {
width: 100%;
border-radius: ${theme.layout.radius};
border: 1px solid ${theme.palette.accents_2};
}
.wrapper {
width: 100%;
padding: ${theme.layout.pageMargin};
display: flex;
flex-direction: column;
box-sizing: border-box;
}
`}</style>
.playground {
width: 100%;
border-radius: ${theme.layout.radius};
border: 1px solid ${theme.palette.accents_2};
}
.wrapper {
width: 100%;
padding: ${theme.layout.pageMargin};
display: flex;
flex-direction: column;
box-sizing: border-box;
}
`}</style>
</div>
</>
)