Skip to content

Commit

Permalink
refactor(xod-client): get rid of recompose from ColorPinWidget due to…
Browse files Browse the repository at this point in the history
… optimization and tweak throttling
  • Loading branch information
brusherru committed Feb 6, 2020
1 parent d4bf58b commit 3aa6cac
Showing 1 changed file with 108 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,111 +3,121 @@ import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { compose, withState, withHandlers, lifecycle } from 'recompose';
import { debounce } from 'throttle-debounce';
import { throttle } from 'throttle-debounce';

import { showColorPickerWidget, tweakNodeProperty } from '../../../actions';
import PinWidget from './PinWidget';
import { hex2color } from '../../ColorPicker';
import ColorPickerWidget from '../../../containers/ColorPickerWidget';
import { isSessionActive } from '../../../../debugger/selectors';

const ColorPinWidget = compose(
withState('value', 'setValue', props => props.value),
withState('focused', 'setFocus', false),
// We have to handle input's selection in a tricky way,
// because we're changing it's value on focus
withState('selection', 'setSelection', [0, 0]),
withState('inputRef', 'setInputRef', null),
// We have to handle it in case we just added a leading quote
// before the literal
lifecycle({
componentDidUpdate(prevProps) {
if (prevProps.selection !== this.props.selection && this.props.inputRef) {
this.props.inputRef.setSelectionRange(
this.props.selection[0],
this.props.selection[1]
);
}
},
}),
withHandlers({
commit: ({ onChange }) => debounce(200, value => onChange(value)),
}),
withHandlers({
onChangeHandler: ({
entityId,
kind,
keyName,
isActiveSession,
tweakColor,
setValue,
commit,
}) => value => {
setValue(value);
commit(value);
if (isActiveSession) {
tweakColor(entityId, kind, keyName, value);
}
},
}),
withHandlers({
onInputChange: ({ onChangeHandler }) => event =>
onChangeHandler(event.target.value),
onWidgetChange: ({ onChangeHandler }) => color =>
onChangeHandler(color.hex),
onFocus: props => event => {
props.setSelection([
event.target.selectionStart,
event.target.selectionEnd,
]);
props.setFocus(true);
},
onBlur: props => _ => {
props.setFocus(false);
props.setSelection([0, 0]);
props.onBlur();
},
})
)(props => (
<PinWidget
elementId={props.elementId}
label={props.label}
dataType={props.dataType}
isConnected={props.isConnected}
isInvalid={props.isInvalid}
deducedType={props.deducedType}
isLastVariadicGroup={props.isLastVariadicGroup}
isBindable={props.isBindable}
direction={props.direction}
>
<span className="inspector-input-wrapper">
<input
className="inspectorTextInput"
type="text"
id={props.elementId}
value={props.value}
onChange={props.onInputChange}
onFocus={props.onFocus}
onBlur={props.onBlur}
onKeyDown={props.onKeyDown}
spellCheck={false}
ref={props.setInputRef}
/>
<button
className="ClorPicker_toggleBtn"
style={{ background: props.value }}
onClick={() => props.showColorPickerWidget(`#${props.inputRef.id}`)}
/>
</span>
<ColorPickerWidget
color={hex2color(props.value)}
onChange={props.onWidgetChange}
/>
</PinWidget>
));
class ColorPinWidget extends React.Component {
constructor(props) {
super(props);
this.state = {
value: props.value,
focused: false,
selection: [0, 0],
};
this.inputRef = null;

this.onValueTweaked = throttle(50, this.onValueTweaked.bind(this));

this.onChangeHandler = this.onChangeHandler.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.onWidgetChange = this.onWidgetChange.bind(this);
this.onFocus = this.onFocus.bind(this);
this.onBlur = this.onBlur.bind(this);
}
componentDidUpdate(prevProps) {
if (prevProps.selection !== this.state.selection && this.inputRef) {
this.inputRef.setSelectionRange(
this.state.selection[0],
this.state.selection[1]
);
}
}

onValueTweaked(value) {
const { entityId, kind, keyName, tweakColor } = this.props;
return tweakColor(entityId, kind, keyName, value);
}
onChangeHandler(value) {
this.setState({ value });
this.props.onChange(value);
if (this.props.isActiveSession) {
this.onValueTweaked(value);
}
}
onInputChange(event) {
this.onChangeHandler(event.target.value);
}
onWidgetChange(color) {
this.onChangeHandler(color.hex);
}
onFocus(event) {
this.setState({
focused: true,
selection: [event.target.selectionStart, event.target.selectionEnd],
});
}
onBlur() {
this.setState({
focused: false,
selection: [0, 0],
});
this.props.onBlur();
}

render() {
return (
<PinWidget
elementId={this.props.elementId}
label={this.props.label}
dataType={this.props.dataType}
isConnected={this.props.isConnected}
isInvalid={this.props.isInvalid}
deducedType={this.props.deducedType}
isLastVariadicGroup={this.props.isLastVariadicGroup}
isBindable={this.props.isBindable}
direction={this.props.direction}
>
<span className="inspector-input-wrapper">
<input
className="inspectorTextInput"
type="text"
id={this.props.elementId}
value={this.props.value}
onChange={this.onInputChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
onKeyDown={this.props.onKeyDown}
spellCheck={false}
ref={el => {
this.inputRef = el;
}}
/>
<button
className="ClorPicker_toggleBtn"
style={{ background: this.props.value }}
onClick={() =>
this.props.showColorPickerWidget(`#${this.inputRef.id}`)
}
/>
</span>
<ColorPickerWidget
color={hex2color(this.props.value)}
onChange={this.onWidgetChange}
/>
</PinWidget>
);
}
}

ColorPinWidget.propTypes = {
entityId: PropTypes.string.isRequired,
keyName: PropTypes.string.isRequired,
kind: PropTypes.string.isRequired,
elementId: PropTypes.string.isRequired,
label: PropTypes.string,
dataType: PropTypes.string,
Expand All @@ -117,12 +127,14 @@ ColorPinWidget.propTypes = {
isBindable: PropTypes.bool,
deducedType: PropTypes.object,
direction: PropTypes.string,
isActiveSession: PropTypes.bool,

value: PropTypes.string,
onBlur: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
onKeyDown: PropTypes.func.isRequired,
showColorPickerWidget: PropTypes.func.isRequired,
tweakColor: PropTypes.func.isRequired,
};

ColorPinWidget.defaultProps = {
Expand Down

0 comments on commit 3aa6cac

Please sign in to comment.