Skip to content

Instantly share code, notes, and snippets.

@pavel-lens
Created April 19, 2017 16:25
Show Gist options
  • Save pavel-lens/0b474b11d919092b262460101f797779 to your computer and use it in GitHub Desktop.
Save pavel-lens/0b474b11d919092b262460101f797779 to your computer and use it in GitHub Desktop.
import React from 'react'
import classnames from 'classnames'
import './revert-apply.scss'
const getClassNames = (props) => classnames(
'revert-apply',
{
bordered: props.bordered,
},
props.className,
)
export class SbRevertApply extends React.Component {
constructor(props) {
super(props)
this.state = {
touched: false,
}
this.renderButtons = this.renderButtons.bind(this)
this.createHandleChange = this.createHandleChange.bind(this)
this.handleApplyClick = this.handleApplyClick.bind(this)
this.handleRevertClick = this.handleRevertClick.bind(this)
}
createHandleChange(callback) {
// This has to be a ES5 function, because we need to access its `arguments`
return (function() {
if (!callback) {
return
}
if (!this.state.touched) {
this.setState({ touched: true })
}
// Call the original callback
callback.apply(null, arguments)
}).bind(this)
}
handleApplyClick() {
const { onApplyClick } = this.props
const result = onApplyClick()
// Don't update state if callback is signaling failing behaviour
if (result !== false) {
this.setState({ touched: false })
}
}
handleRevertClick() {
const { onRevertClick } = this.props
const result = onRevertClick()
// Don't update state if callback is signaling failing behaviour
if (result !== false) {
this.setState({ touched: false })
}
}
renderButtons() {
const { buttonsPosition } = this.props
const disabled = !this.state.touched
return (
<div>
<Button onClick={this.handleRevertClick} disabled={disabled} >Revert</Button>
<Button onClick={this.handleApplyClick} disabled={disabled} >Apply</Button>
</div>
)
}
renderWrappedChildren(children) {
return React.Children.map(children, (child) => {
// This is support for non-node elements (eg. pure text), they have no props
if (!child.props) {
return child
}
if (child.props.children) {
return React.cloneElement(child, {
children: this.renderWrappedChildren(child.props.children),
onChange: this.createHandleChange(child.props.onChange),
})
}
return React.cloneElement(child, {
onChange: this.createHandleChange(child.props.onChange),
})
},
)
}
render() {
const { buttonsPosition } = this.props
const classNames = getClassNames(this.props)
const buttonsNode = this.renderButtons()
const childrenWithProps = this.renderWrappedChildren(this.props.children)
return (
<div className={classNames}>
{buttonsPosition === 'top' && buttonsNode}
{childrenWithProps}
{buttonsPosition !== 'top' && buttonsNode}
</div>
)
}
}
SbRevertApply.defaultProps = {
bordered: true,
buttonsPosition: 'top',
touched: false,
onApplyClick: () => {},
onRevertClick: () => {},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment