wix-style-react
Version:
145 lines (129 loc) • 4.22 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import Heading from '../Heading';
import Input from '../Input/Input';
import { st, classes } from './EditableTitle.st.css';
import { WixStyleReactContext } from '../WixStyleReactProvider/context';
import { dataHooks } from './constants';
const DEFAULT_MAX_LENGTH = 100;
class EditableTitle extends React.Component {
constructor(props) {
super(props);
this.state = {
focus: false,
value: props.initialValue || '',
};
}
componentDidMount() {
if (this.props.autoFocus) this.onFocus();
}
onChange = e => {
this.setState({ value: e.target.value });
};
showPlaceholder = () => !this.state.value && this.props.defaultValue;
onFocus = () => {
const value = this.state.value || this.props.defaultValue;
const selectAll = !this.state.focus;
this.setState({ focus: true, value }, () => {
this.wsrInput.focus();
selectAll && this.wsrInput.select();
});
};
render() {
const { dataHook, className, maxLength } = this.props;
const focused = this.state.focus;
return (
<WixStyleReactContext.Consumer>
{({ reducedSpacingAndImprovedLayout }) => (
<div
className={st(
classes.root,
{ reducedSpacingAndImprovedLayout },
className,
)}
data-hook={dataHook}
tabIndex={0}
onFocus={this.onFocus}
onClick={this.onFocus}
>
<div
data-hook={dataHooks.heading}
className={st(classes.headingWrapper, {
focused,
showPlaceholder: !!this.showPlaceholder(),
})}
>
<Heading ellipsis appearance="H1" className={classes.heading}>
{this.props.value ||
this.state.value ||
this.props.defaultValue}
</Heading>
</div>
<div
className={st(classes.activationIndicator, {
focused,
})}
>
{this.props.value || this.state.value || this.props.defaultValue}
</div>
<div
className={st(classes.renamingField, {
focused,
})}
data-hook={dataHooks.renamingField}
onFocus={e =>
// input does not pass his event so we need to catch it
e.stopPropagation()
}
>
<Input
autoSelect={false}
textOverflow="clip"
maxLength={maxLength || DEFAULT_MAX_LENGTH}
onChange={
this.props.onChange ? this.props.onChange : this.onChange
}
value={this.props.value ? this.props.value : this.state.value}
ref={wsrInput => (this.wsrInput = wsrInput)}
onBlur={this.onValueSubmission}
onEnterPressed={this.onEnterPressed}
/>
</div>
</div>
)}
</WixStyleReactContext.Consumer>
);
}
onEnterPressed = () => {
this.wsrInput.blur();
};
onValueSubmission = () => {
const value = this.state.value || this.props.defaultValue;
this.setState({ value, focus: false }, () => {
if (typeof this.props.onSubmit === 'function') {
this.props.onSubmit(value);
}
});
};
}
EditableTitle.displayName = 'EditableTitle';
EditableTitle.defaultProps = {
defaultValue: '',
};
EditableTitle.propTypes = {
/** Value - initial value to display */
initialValue: PropTypes.string,
/** default - value to display when empty, when clicked the input gets this value */
defaultValue: PropTypes.string,
/** onSubmit - invoked when done editing */
onSubmit: PropTypes.func,
/** length - maximum chars the input can get */
maxLength: PropTypes.number,
/** autoFocus - focus element on mount */
autoFocus: PropTypes.bool,
/** onChange-invoked when editing */
onChange: PropTypes.func,
/** value- the controlled value of the input */
value: PropTypes.string,
};
export default EditableTitle;