flex-template-web/src/forms/SendMessageForm/SendMessageForm.js
Hannu Lyytikainen cdfd6e0886 Change final form props spreading
Change props spreading so that the whole props object is available to
the form and required props can be destructured from that.
2018-06-01 12:42:08 +03:00

141 lines
4 KiB
JavaScript

import React, { Component } from 'react';
import { string, bool, func } from 'prop-types';
import { compose } from 'redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { Form as FinalForm } from 'react-final-form';
import classNames from 'classnames';
import { Form, FieldTextInput, SecondaryButton } from '../../components';
import { propTypes } from '../../util/types';
import css from './SendMessageForm.css';
const BLUR_TIMEOUT_MS = 100;
const IconSendMessage = () => {
return (
<svg
className={css.sendIcon}
width="14"
height="14"
viewBox="0 0 14 14"
xmlns="http://www.w3.org/2000/svg"
>
<g className={css.strokeMatter} fill="none" fillRule="evenodd" strokeLinejoin="round">
<path d="M12.91 1L0 7.003l5.052 2.212z" />
<path d="M10.75 11.686L5.042 9.222l7.928-8.198z" />
<path d="M5.417 8.583v4.695l2.273-2.852" />
</g>
</svg>
);
};
class SendMessageFormComponent extends Component {
constructor(props) {
super(props);
this.handleFocus = this.handleFocus.bind(this);
this.handleBlur = this.handleBlur.bind(this);
this.blurTimeoutId = null;
}
handleFocus() {
this.props.onFocus();
window.clearTimeout(this.blurTimeoutId);
}
handleBlur() {
// We only trigger a blur if another focus event doesn't come
// within a timeout. This enables keeping the focus synced when
// focus is switched between the message area and the submit
// button.
this.blurTimeoutId = window.setTimeout(() => {
this.props.onBlur();
}, BLUR_TIMEOUT_MS);
}
render() {
return (
<FinalForm
{...this.props}
render={formRenderProps => {
const {
rootClassName,
className,
messagePlaceholder,
handleSubmit,
inProgress,
sendMessageError,
invalid,
form,
} = formRenderProps;
const classes = classNames(rootClassName || css.root, className);
const submitInProgress = inProgress;
const submitDisabled = invalid || submitInProgress;
return (
<Form className={classes} onSubmit={values => handleSubmit(values, form)}>
<FieldTextInput
inputRootClass={css.textarea}
type="textarea"
id="message"
name="message"
placeholder={messagePlaceholder}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
/>
<div className={css.submitContainer}>
<div className={css.errorContainer}>
{sendMessageError ? (
<p className={css.error}>
<FormattedMessage id="SendMessageForm.sendFailed" />
</p>
) : null}
</div>
<SecondaryButton
className={css.submitButton}
inProgress={submitInProgress}
disabled={submitDisabled}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
>
<IconSendMessage />
<FormattedMessage id="SendMessageForm.sendMessage" />
</SecondaryButton>
</div>
</Form>
);
}}
/>
);
}
}
SendMessageFormComponent.defaultProps = {
rootClassName: null,
className: null,
inProgress: false,
messagePlaceholder: null,
onFocus: () => null,
onBlur: () => null,
sendMessageError: null,
};
SendMessageFormComponent.propTypes = {
rootClassName: string,
className: string,
inProgress: bool,
messagePlaceholder: string,
onSubmit: func.isRequired,
onFocus: func,
onBlur: func,
sendMessageError: propTypes.error,
// from injectIntl
intl: intlShape.isRequired,
};
const SendMessageForm = compose(injectIntl)(SendMessageFormComponent);
SendMessageForm.displayName = 'SendMessageForm';
export default SendMessageForm;