Merge pull request #2237 from paulkaplan/fix-formsy-perf

Keep each input in its own formsy wrapper to improve performance
This commit is contained in:
Paul Kaplan 2018-10-25 10:50:07 -04:00 committed by GitHub
commit d9fa10316b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 111 additions and 97 deletions

View file

@ -21,6 +21,10 @@
} }
} }
.full-width-form {
width: 100%;
}
.textarea-row { .textarea-row {
width: 100%; width: 100%;

View file

@ -5,6 +5,7 @@ const classNames = require('classnames');
const keyMirror = require('keymirror'); const keyMirror = require('keymirror');
const FormattedMessage = require('react-intl').FormattedMessage; const FormattedMessage = require('react-intl').FormattedMessage;
const Formsy = require('formsy-react').default;
const FlexRow = require('../../../components/flex-row/flex-row.jsx'); const FlexRow = require('../../../components/flex-row/flex-row.jsx');
const Avatar = require('../../../components/avatar/avatar.jsx'); const Avatar = require('../../../components/avatar/avatar.jsx');
const InplaceInput = require('../../../components/forms/inplace-input.jsx'); const InplaceInput = require('../../../components/forms/inplace-input.jsx');
@ -111,46 +112,49 @@ class ComposeComment extends React.Component {
</div> </div>
</FlexRow> </FlexRow>
) : null} ) : null}
<InplaceInput <Formsy className="full-width-form">
className={classNames('compose-input', <InplaceInput
MAX_COMMENT_LENGTH - this.state.message.length >= 0 ? 'compose-valid' : 'compose-invalid')} className={classNames('compose-input',
handleUpdate={onUpdate}
name="compose-comment"
type="textarea"
value={this.state.message}
onInput={this.handleInput}
/>
<FlexRow className="compose-bottom-row">
<Button
className="compose-post"
disabled={this.state.status === ComposeStatus.SUBMITTING}
onClick={this.handlePost}
>
{this.state.status === ComposeStatus.SUBMITTING ? (
<FormattedMessage id="comments.posting" />
) : (
<FormattedMessage id="comments.post" />
)}
</Button>
<Button
className="compose-cancel"
onClick={this.handleCancel}
>
<FormattedMessage id="comments.cancel" />
</Button>
<span
className={classNames('compose-limit',
MAX_COMMENT_LENGTH - this.state.message.length >= 0 ? MAX_COMMENT_LENGTH - this.state.message.length >= 0 ?
'compose-valid' : 'compose-invalid')} 'compose-valid' : 'compose-invalid')}
> handleUpdate={onUpdate}
<FormattedMessage name="compose-comment"
id="comments.lengthWarning" type="textarea"
values={{ value={this.state.message}
remainingCharacters: MAX_COMMENT_LENGTH - this.state.message.length onInput={this.handleInput}
}} />
/> <FlexRow className="compose-bottom-row">
</span> <Button
</FlexRow> className="compose-post"
disabled={this.state.status === ComposeStatus.SUBMITTING}
onClick={this.handlePost}
>
{this.state.status === ComposeStatus.SUBMITTING ? (
<FormattedMessage id="comments.posting" />
) : (
<FormattedMessage id="comments.post" />
)}
</Button>
<Button
className="compose-cancel"
onClick={this.handleCancel}
>
<FormattedMessage id="comments.cancel" />
</Button>
<span
className={classNames('compose-limit',
MAX_COMMENT_LENGTH - this.state.message.length >= 0 ?
'compose-valid' : 'compose-invalid')}
>
<FormattedMessage
id="comments.lengthWarning"
values={{
remainingCharacters: MAX_COMMENT_LENGTH - this.state.message.length
}}
/>
</span>
</FlexRow>
</Formsy>
</FlexRow> </FlexRow>
</div> </div>
); );

View file

@ -97,7 +97,7 @@ const PreviewPresentation = ({
<ShareBanner onShare={onShare} /> <ShareBanner onShare={onShare} />
)} )}
{ projectInfo && projectInfo.author && projectInfo.author.id && ( { projectInfo && projectInfo.author && projectInfo.author.id && (
<Formsy onKeyPress={onKeyPress}> <React.Fragment>
<div className="inner"> <div className="inner">
<FlexRow className="preview-row force-row"> <FlexRow className="preview-row force-row">
<FlexRow className="project-header"> <FlexRow className="project-header">
@ -109,20 +109,22 @@ const PreviewPresentation = ({
</a> </a>
<div className="title"> <div className="title">
{editable ? {editable ?
<InplaceInput <Formsy onKeyPress={onKeyPress}>
className="project-title" <InplaceInput
handleUpdate={onUpdate} className="project-title"
name="title" handleUpdate={onUpdate}
validationErrors={{ name="title"
maxLength: intl.formatMessage({ validationErrors={{
id: 'project.titleMaxLength' maxLength: intl.formatMessage({
}) id: 'project.titleMaxLength'
}} })
validations={{ }}
maxLength: 100 validations={{
}} maxLength: 100
value={projectInfo.title} }}
/> : value={projectInfo.title}
/>
</Formsy> :
<React.Fragment> <React.Fragment>
<div <div
className="project-title no-edit" className="project-title no-edit"
@ -217,27 +219,29 @@ const PreviewPresentation = ({
<FormattedMessage id="project.instructionsLabel" /> <FormattedMessage id="project.instructionsLabel" />
</div> </div>
{editable ? {editable ?
<InplaceInput <Formsy onKeyPress={onKeyPress}>
className={classNames( <InplaceInput
'project-description-edit', className={classNames(
{remixes: parentInfo && parentInfo.author} 'project-description-edit',
)} {remixes: parentInfo && parentInfo.author}
handleUpdate={onUpdate} )}
name="instructions" handleUpdate={onUpdate}
placeholder="Tell people how to use your project (such as which keys to press)." name="instructions"
type="textarea" placeholder="Tell people how to use your project (such as which keys to press)."
validationErrors={{ type="textarea"
maxLength: 'Sorry description is too long' validationErrors={{
// maxLength: props.intl.formatMessage({ maxLength: 'Sorry description is too long'
// id: 'project.descriptionMaxLength' // maxLength: props.intl.formatMessage({
// }) // id: 'project.descriptionMaxLength'
}} // })
validations={{ }}
// TODO: actual 5000 validations={{
maxLength: 1000 // TODO: actual 5000
}} maxLength: 1000
value={projectInfo.instructions} }}
/> : value={projectInfo.instructions}
/>
</Formsy> :
<div className="project-description"> <div className="project-description">
{decorateText(projectInfo.instructions)} {decorateText(projectInfo.instructions)}
</div> </div>
@ -248,28 +252,30 @@ const PreviewPresentation = ({
<FormattedMessage id="project.notesAndCreditsLabel" /> <FormattedMessage id="project.notesAndCreditsLabel" />
</div> </div>
{editable ? {editable ?
<InplaceInput <Formsy onKeyPress={onKeyPress}>
className={classNames( <InplaceInput
'project-description-edit', className={classNames(
'last', 'project-description-edit',
{remixes: parentInfo && parentInfo.author} 'last',
)} {remixes: parentInfo && parentInfo.author}
handleUpdate={onUpdate} )}
name="description" handleUpdate={onUpdate}
placeholder="How did you make this project? Did you use ideas scripts or artwork from other people? Thank them here." name="description"
type="textarea" placeholder="How did you make this project? Did you use ideas scripts or artwork from other people? Thank them here."
validationErrors={{ type="textarea"
maxLength: 'Sorry description is too long' validationErrors={{
// maxLength: props.intl.formatMessage({ maxLength: 'Sorry description is too long'
// id: 'project.descriptionMaxLength' // maxLength: props.intl.formatMessage({
// }) // id: 'project.descriptionMaxLength'
}} // })
validations={{ }}
// TODO: actual 5000 validations={{
maxLength: 1000 // TODO: actual 5000
}} maxLength: 1000
value={projectInfo.description} }}
/> : value={projectInfo.description}
/>
</Formsy> :
<div className="project-description last"> <div className="project-description last">
{decorateText(projectInfo.description)} {decorateText(projectInfo.description)}
</div> </div>
@ -401,7 +407,7 @@ const PreviewPresentation = ({
</FlexRow> </FlexRow>
</div> </div>
</div> </div>
</Formsy> </React.Fragment>
)} )}
</div> </div>
); );