use HOC for popout state, remove react-addons-shallow-compare

main
raboid 6 years ago committed by Michael Fix
parent 64cccc1d90
commit 9d37f9bf99

@ -1,33 +1,19 @@
import React from 'react' import React from 'react'
import shallowCompare from 'react-addons-shallow-compare'
import ImagePicker from './ImagePicker' import ImagePicker from './ImagePicker'
import ColorPicker from './ColorPicker' import ColorPicker from './ColorPicker'
import Popout from './Popout' import Popout, { managePopout } from './Popout'
import { COLORS, DEFAULT_BG_COLOR } from '../lib/constants' import { COLORS, DEFAULT_BG_COLOR } from '../lib/constants'
import { validateColor } from '../lib/colors' import { validateColor } from '../lib/colors'
import { toggle, capitalize, stringifyRGBA } from '../lib/util' import { capitalize, stringifyRGBA } from '../lib/util'
class BackgroundSelect extends React.Component { class BackgroundSelect extends React.PureComponent {
state = { isVisible: false, mounted: false } state = { mounted: false }
componentDidMount() { componentDidMount() {
this.setState({ mounted: true }) this.setState({ mounted: true })
} }
shouldComponentUpdate(prevProps, prevState) {
return [
prevState.isVisible !== this.state.isVisible,
prevProps.color !== this.props.color,
prevState.isVisible && shallowCompare(this, prevProps, prevState)
].some(Boolean)
}
toggle = e => {
e.stopPropagation()
this.setState(toggle('isVisible'))
}
selectTab = name => { selectTab = name => {
if (this.props.mode !== name) { if (this.props.mode !== name) {
this.props.onChange({ backgroundMode: name }) this.props.onChange({ backgroundMode: name })
@ -37,8 +23,8 @@ class BackgroundSelect extends React.Component {
handlePickColor = ({ rgb }) => this.props.onChange({ backgroundColor: stringifyRGBA(rgb) }) handlePickColor = ({ rgb }) => this.props.onChange({ backgroundColor: stringifyRGBA(rgb) })
render() { render() {
const { color, mode, image, onChange, aspectRatio } = this.props const { color, mode, image, onChange, aspectRatio, isVisible, toggleVisibility } = this.props
const { isVisible, mounted } = this.state const { mounted } = this.state
let background = let background =
typeof color === 'string' typeof color === 'string'
@ -58,17 +44,12 @@ class BackgroundSelect extends React.Component {
return ( return (
<div className="bg-select-container"> <div className="bg-select-container">
<div className={`bg-select-display ${isVisible ? 'is-visible' : ''}`}> <div className={`bg-select-display ${isVisible ? 'is-visible' : ''}`}>
<div className="bg-color-container" onClick={this.toggle}> <div className="bg-color-container" onClick={toggleVisibility}>
<div className="bg-color-alpha" /> <div className="bg-color-alpha" />
<div className="bg-color" /> <div className="bg-color" />
</div> </div>
</div> </div>
<Popout <Popout pointerLeft="15px" hidden={!isVisible} style={{ width: '222px' }}>
pointerLeft="15px"
onClickOutside={this.toggle}
hidden={!isVisible}
style={{ width: '222px' }}
>
<div className="picker-tabs"> <div className="picker-tabs">
{['color', 'image'].map(tab => ( {['color', 'image'].map(tab => (
<div <div
@ -166,4 +147,4 @@ class BackgroundSelect extends React.Component {
} }
} }
export default BackgroundSelect export default managePopout(BackgroundSelect)

@ -5,9 +5,7 @@ import { COLORS, EXPORT_SIZES } from '../lib/constants'
import Button from './Button' import Button from './Button'
import Input from './Input' import Input from './Input'
import CopyButton from './CopyButton' import CopyButton from './CopyButton'
import Popout from './Popout' import Popout, { managePopout } from './Popout'
import { toggle } from '../lib/util'
const toIFrame = url => const toIFrame = url =>
`<iframe `<iframe
@ -35,15 +33,6 @@ const CopyEmbed = withRouter(
const popoutStyle = { width: '280px', right: 0 } const popoutStyle = { width: '280px', right: 0 }
class ExportMenu extends React.PureComponent { class ExportMenu extends React.PureComponent {
state = {
isVisible: false
}
toggle = e => {
e.stopPropagation()
this.setState(toggle('isVisible'))
}
handleInputChange = ({ target: { name, value } }) => this.props.onChange(name, value) handleInputChange = ({ target: { name, value } }) => this.props.onChange(name, value)
handleExportSizeChange = selectedSize => () => this.props.onChange('exportSize', selectedSize) handleExportSizeChange = selectedSize => () => this.props.onChange('exportSize', selectedSize)
@ -51,8 +40,7 @@ class ExportMenu extends React.PureComponent {
handleExport = format => () => this.props.export(format) handleExport = format => () => this.props.export(format)
render() { render() {
const { exportSize, filename } = this.props const { exportSize, filename, isVisible, toggleVisibility } = this.props
const { isVisible } = this.state
return ( return (
<div className="export-menu-container"> <div className="export-menu-container">
@ -63,7 +51,7 @@ class ExportMenu extends React.PureComponent {
color={COLORS.PURPLE} color={COLORS.PURPLE}
padding="0 16px" padding="0 16px"
selected={isVisible} selected={isVisible}
onClick={this.toggle} onClick={toggleVisibility}
> >
Export Export
</Button> </Button>
@ -71,7 +59,6 @@ class ExportMenu extends React.PureComponent {
<Popout <Popout
hidden={!isVisible} hidden={!isVisible}
borderColor={COLORS.PURPLE} borderColor={COLORS.PURPLE}
onClickOutside={this.toggle}
pointerRight="28px" pointerRight="28px"
style={popoutStyle} style={popoutStyle}
> >
@ -183,4 +170,4 @@ class ExportMenu extends React.PureComponent {
} }
} }
export default ExportMenu export default managePopout(ExportMenu)

@ -3,16 +3,38 @@ import enhanceWithClickOutside from 'react-click-outside'
import WindowPointer from './WindowPointer' import WindowPointer from './WindowPointer'
import { COLORS } from '../lib/constants' import { COLORS } from '../lib/constants'
import { toggle } from '../lib/util'
export const managePopout = WrappedComponent => {
class PopoutManager extends React.Component {
state = {
isVisible: false
}
toggleVisibility = () => this.setState(toggle('isVisible'))
handleClickOutside = () => this.setState({ isVisible: false })
render() {
return (
<WrappedComponent
{...this.props}
isVisible={this.state.isVisible}
toggleVisibility={this.toggleVisibility}
/>
)
}
}
return enhanceWithClickOutside(PopoutManager)
}
class Popout extends React.PureComponent { class Popout extends React.PureComponent {
static defaultProps = { static defaultProps = {
borderColor: COLORS.SECONDARY, borderColor: COLORS.SECONDARY,
style: {}, style: {}
onClickOutside: () => {}
} }
handleClickOutside = e => !this.props.hidden && this.props.onClickOutside(e)
render() { render() {
const { children, borderColor, style, hidden, pointerLeft, pointerRight } = this.props const { children, borderColor, style, hidden, pointerLeft, pointerRight } = this.props
@ -41,4 +63,4 @@ class Popout extends React.PureComponent {
} }
} }
export default enhanceWithClickOutside(Popout) export default Popout

@ -5,7 +5,7 @@ import ThemeSelect from './ThemeSelect'
import FontSelect from './FontSelect' import FontSelect from './FontSelect'
import Slider from './Slider' import Slider from './Slider'
import Toggle from './Toggle' import Toggle from './Toggle'
import Popout from './Popout' import Popout, { managePopout } from './Popout'
import Button from './Button' import Button from './Button'
import Presets from './Presets' import Presets from './Presets'
import { COLORS, DEFAULT_PRESETS } from '../lib/constants' import { COLORS, DEFAULT_PRESETS } from '../lib/constants'
@ -202,7 +202,6 @@ const settingButtonStyle = {
class Settings extends React.PureComponent { class Settings extends React.PureComponent {
state = { state = {
presets: DEFAULT_PRESETS, presets: DEFAULT_PRESETS,
isVisible: false,
selectedMenu: 'Window', selectedMenu: 'Window',
showPresets: false, showPresets: false,
previousSettings: null, previousSettings: null,
@ -220,11 +219,6 @@ class Settings extends React.PureComponent {
})) }))
} }
toggleVisible = e => {
e.stopPropagation()
this.setState(toggle('isVisible'))
}
togglePresets = () => this.setState(toggle('showPresets')) togglePresets = () => this.setState(toggle('showPresets'))
selectMenu = selectedMenu => () => this.setState({ selectedMenu }) selectMenu = selectedMenu => () => this.setState({ selectedMenu })
@ -344,15 +338,8 @@ class Settings extends React.PureComponent {
} }
render() { render() {
const { const { selectedMenu, showPresets, presets, previousSettings, widthChanging } = this.state
isVisible, const { preset, isVisible, toggleVisibility } = this.props
selectedMenu,
showPresets,
presets,
previousSettings,
widthChanging
} = this.state
const { preset } = this.props
return ( return (
<div className="settings-container" ref={this.settingsRef}> <div className="settings-container" ref={this.settingsRef}>
@ -361,13 +348,12 @@ class Settings extends React.PureComponent {
center center
selected={isVisible} selected={isVisible}
style={settingButtonStyle} style={settingButtonStyle}
onClick={this.toggleVisible} onClick={toggleVisibility}
> >
<SettingsIcon /> <SettingsIcon />
</Button> </Button>
<Popout <Popout
pointerLeft="15px" pointerLeft="15px"
onClickOutside={this.toggleVisible}
hidden={!isVisible} hidden={!isVisible}
style={{ style={{
position: widthChanging ? 'fixed' : 'absolute', position: widthChanging ? 'fixed' : 'absolute',
@ -432,4 +418,4 @@ class Settings extends React.PureComponent {
} }
} }
export default Settings export default managePopout(Settings)

@ -38,7 +38,6 @@
"next-offline": "^3.3.1", "next-offline": "^3.3.1",
"prettier": "^1.14.3", "prettier": "^1.14.3",
"react": "^16.7.0", "react": "^16.7.0",
"react-addons-shallow-compare": "^15.6.2",
"react-click-outside": "^3.0.0", "react-click-outside": "^3.0.0",
"react-codemirror2": "^5.1.0", "react-codemirror2": "^5.1.0",
"react-color": "^2.17.0", "react-color": "^2.17.0",

@ -2957,7 +2957,7 @@ fast-levenshtein@~2.0.4:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.4: fbjs@^0.8.1, fbjs@^0.8.16:
version "0.8.17" version "0.8.17"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
@ -5616,14 +5616,6 @@ rc@^1.2.7:
minimist "^1.2.0" minimist "^1.2.0"
strip-json-comments "~2.0.1" strip-json-comments "~2.0.1"
react-addons-shallow-compare@^15.6.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/react-addons-shallow-compare/-/react-addons-shallow-compare-15.6.2.tgz#198a00b91fc37623db64a28fd17b596ba362702f"
integrity sha1-GYoAuR/DdiPbZKKP0XtZa6NicC8=
dependencies:
fbjs "^0.8.4"
object-assign "^4.1.0"
react-click-outside@^3.0.0: react-click-outside@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/react-click-outside/-/react-click-outside-3.0.1.tgz#6e77e84d2f17afaaac26dbad743cbbf909f5e24c" resolved "https://registry.yarnpkg.com/react-click-outside/-/react-click-outside-3.0.1.tgz#6e77e84d2f17afaaac26dbad743cbbf909f5e24c"

Loading…
Cancel
Save