Update ExportMenu to use Popout, Button, Input

main
raboid 6 years ago committed by Michael Fix
parent 0c22633853
commit e5b3d39d4e

@ -1,11 +1,11 @@
import React from 'react' import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'
import { withRouter } from 'next/router' import { withRouter } from 'next/router'
import { COLORS, EXPORT_SIZES } from '../lib/constants' import { COLORS, EXPORT_SIZES } from '../lib/constants'
import Button from './Button' import Button from './Button'
import Input from './Input'
import CopyButton from './CopyButton' import CopyButton from './CopyButton'
import WindowPointer from './WindowPointer' import Popout from './Popout'
import { toggle } from '../lib/util' import { toggle } from '../lib/util'
@ -20,53 +20,35 @@ const toIFrame = url =>
const CopyEmbed = withRouter( const CopyEmbed = withRouter(
React.memo( React.memo(
({ router: { asPath } }) => ( ({ router: { asPath } }) => (
<React.Fragment>
<CopyButton text={toIFrame(asPath)}> <CopyButton text={toIFrame(asPath)}>
{({ copied }) => ( {({ copied }) => (
<button className="copy-button">{copied ? 'Copied!' : 'Copy Embed'}</button> <Button
center
title={copied ? 'Copied!' : 'Copy Embed'}
color={COLORS.PURPLE}
padding="12px 16px"
flex="1 0 68px"
/>
)} )}
</CopyButton> </CopyButton>
<style jsx>
{`
.copy-button {
display: flex;
flex: 1;
flex-basis: 68px;
justify-content: center;
align-items: center;
padding: 12px 16px;
font-size: 12px;
white-space: nowrap;
user-select: none;
cursor: pointer;
outline: none;
border: none;
background: inherit;
color: ${COLORS.PURPLE};
border-right: 1px solid ${COLORS.PURPLE};
}
.copy-button:hover {
opacity: 1;
}
`}
</style>
</React.Fragment>
), ),
(prevProps, nextProps) => prevProps.router.asPath === nextProps.router.asPath (prevProps, nextProps) => prevProps.router.asPath === nextProps.router.asPath
) )
) )
const popoutStyle = { width: '280px', right: 0 }
class ExportMenu extends React.PureComponent { class ExportMenu extends React.PureComponent {
state = { state = {
isVisible: false isVisible: false
} }
toggle = () => this.setState(toggle('isVisible')) toggle = e => {
e.stopPropagation()
handleClickOutside = () => this.setState({ isVisible: false }) this.setState(toggle('isVisible'))
}
handleInputChange = e => this.props.onChange(e.target.name, e.target.value) handleInputChange = ({ target: { name, value } }) => this.props.onChange(name, value)
handleExportSizeChange = selectedSize => () => this.props.onChange('exportSize', selectedSize) handleExportSizeChange = selectedSize => () => this.props.onChange('exportSize', selectedSize)
@ -77,180 +59,120 @@ class ExportMenu extends React.PureComponent {
const { isVisible } = this.state const { isVisible } = this.state
return ( return (
<div className="export-menu-container" id="export-menu"> <div className="export-menu-container">
<div className="flex">
<Button <Button
selected={isVisible} border
className="exportButton" large
onClick={this.toggle}
title="Export" title="Export"
color={COLORS.PURPLE} color={COLORS.PURPLE}
padding="0 16px"
selected={isVisible}
onClick={this.toggle}
/> />
<div className="export-menu" hidden={!isVisible}> </div>
<WindowPointer fromRight="28px" color={COLORS.PURPLE} /> <Popout
<div className="export-option filename-option"> hidden={!isVisible}
<span>File name</span> borderColor={COLORS.PURPLE}
<input onClickOutside={this.toggle}
pointerRight="28px"
style={popoutStyle}
>
<div className="export-row">
<span className="filename">File name</span>
<Input
title="filename" title="filename"
placeholder="carbon" placeholder="carbon"
value={filename} value={filename}
name="filename" name="filename"
onChange={this.handleInputChange} onChange={this.handleInputChange}
color={COLORS.PURPLE}
/> />
</div> </div>
<div className="export-option"> <div className="export-row">
<div className="size-container">
<span>Size</span> <span>Size</span>
<div> <div className="flex">
{EXPORT_SIZES.map(({ name }) => ( {EXPORT_SIZES.map(({ name }, i) => (
<button <Button
center
key={name} key={name}
title={name}
hoverColor={COLORS.PURPLE}
margin={i === EXPORT_SIZES.length - 1 ? 0 : '0 10px 0 0'}
color={exportSize === name ? COLORS.PURPLE : COLORS.DARK_PURPLE}
onClick={this.handleExportSizeChange(name)} onClick={this.handleExportSizeChange(name)}
className={`size-button ${exportSize === name ? 'selected' : ''}`} />
>
{name}
</button>
))} ))}
</div> </div>
</div> </div>
</div> <div className="export-row">
<div className="export-option"> <Button center title="Open" color={COLORS.PURPLE} onClick={this.handleExport('open')} />
<button className="open-button" onClick={this.handleExport('open')}>
Open
</button>
<CopyEmbed /> <CopyEmbed />
<div className="save-container"> <div className="save-container">
<span>Save as</span> <span>Save as</span>
<div> <div>
<button onClick={this.handleExport('png')} className="save-button" id="export-png"> <Button
PNG center
</button> title="PNG"
<button onClick={this.handleExport('svg')} className="save-button" id="export-svg"> margin="0 8px 0 0"
SVG hoverColor={COLORS.PURPLE}
</button> color={COLORS.DARK_PURPLE}
</div> onClick={this.handleExport('png')}
/>
<Button
center
title="SVG"
hoverColor={COLORS.PURPLE}
color={COLORS.DARK_PURPLE}
onClick={this.handleExport('svg')}
/>
</div> </div>
</div> </div>
</div> </div>
</Popout>
<style jsx> <style jsx>
{` {`
button {
font-size: 12px;
display: flex;
user-select: none;
cursor: pointer;
background: inherit;
outline: none;
border: none;
padding: 0;
color: ${COLORS.PURPLE};
}
button:hover {
opacity: 1;
}
input {
padding: 8px 16px;
width: 100%;
font-size: 12px;
color: ${COLORS.PURPLE};
background: transparent;
border: none;
outline: none;
}
input::placeholder {
color: ${COLORS.PURPLE};
opacity: 0.4;
}
.export-menu-container { .export-menu-container {
position: relative; position: relative;
color: ${COLORS.PURPLE}; color: ${COLORS.PURPLE};
font-size: 12px;
} }
.export-menu { .flex {
box-sizing: content-box; display: flex;
position: absolute; height: 100%;
margin-top: 10px;
width: 280px;
border-radius: 3px;
border: 2px solid ${COLORS.PURPLE};
right: 0;
background-color: ${COLORS.BLACK};
} }
.filename-option { .export-row {
display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0 16px; padding: 8px 16px;
}
.filename-option input {
padding: 8px 0;
width: 60%;
text-align: right;
}
.export-option {
display: flex;
border-bottom: 1px solid ${COLORS.PURPLE}; border-bottom: 1px solid ${COLORS.PURPLE};
} }
.export-option:last-child { .export-row > :global(button) {
border-bottom: none; border-right: 1px solid ${COLORS.PURPLE};
}
.size-container {
display: flex;
flex: 1;
padding: 8px 16px;
justify-content: space-between;
} }
.size-container > div { .export-row:last-child {
display: flex; border-bottom: none;
padding: 0;
} }
.size-button { .filename {
line-height: 0; flex-basis: 72px;
opacity: 0.4;
margin-right: 10px;
}
.size-button:last-child {
margin-right: 0;
}
.size-button.selected {
opacity: 1;
} }
.open-button,
.save-container { .save-container {
display: flex; display: flex;
flex: 1; flex: 1;
flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 12px 16px; padding: 12px 16px;
} }
.open-button {
border-right: 1px solid ${COLORS.PURPLE};
}
.save-container {
flex-direction: column;
}
.save-container > span {
margin-bottom: 6px;
}
.save-container > div { .save-container > div {
margin-top: 6px;
display: flex; display: flex;
} flex: 1;
.save-button {
opacity: 0.4;
}
.save-button:first-child {
margin-right: 8px;
} }
`} `}
</style> </style>
@ -259,4 +181,4 @@ class ExportMenu extends React.PureComponent {
} }
} }
export default enhanceWithClickOutside(ExportMenu) export default ExportMenu

@ -488,6 +488,7 @@ export const COLORS = {
DARK_GRAY: '#393939', DARK_GRAY: '#393939',
HOVER: '#1F1F1F', HOVER: '#1F1F1F',
PURPLE: '#C198FB', PURPLE: '#C198FB',
DARK_PURPLE: '#55436F',
RED: 'red' RED: 'red'
} }

Loading…
Cancel
Save