From aec14e64facc3e172e60af1cba18b075bf52a6af Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 23 Apr 2019 17:59:19 +0100 Subject: [PATCH] Throttle validation in response to user input This avoids the case of the password complexity progress jumping wildly for every character you type. --- src/components/views/elements/Field.js | 14 +++++++++++--- src/components/views/elements/Validation.js | 1 - 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/Field.js b/src/components/views/elements/Field.js index 8f0746dff2..91447a8846 100644 --- a/src/components/views/elements/Field.js +++ b/src/components/views/elements/Field.js @@ -18,6 +18,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import sdk from '../../../index'; +import { throttle } from 'lodash'; + +// Invoke validation from user input (when typing, etc.) at most once every N ms. +const VALIDATION_THROTTLE_MS = 200; export default class Field extends React.PureComponent { static propTypes = { @@ -64,9 +68,7 @@ export default class Field extends React.PureComponent { }; onChange = (ev) => { - this.validate({ - focused: true, - }); + this.validateOnChange(); // Parent component may have supplied its own `onChange` as well if (this.props.onChange) { this.props.onChange(ev); @@ -103,6 +105,12 @@ export default class Field extends React.PureComponent { }); } + validateOnChange = throttle(() => { + this.validate({ + focused: true, + }); + }, VALIDATION_THROTTLE_MS); + render() { const { element, prefix, onValidate, children, ...inputProps } = this.props; diff --git a/src/components/views/elements/Validation.js b/src/components/views/elements/Validation.js index c37970e534..31363b87c8 100644 --- a/src/components/views/elements/Validation.js +++ b/src/components/views/elements/Validation.js @@ -37,7 +37,6 @@ import classNames from 'classnames'; */ export default function withValidation({ description, rules }) { return async function onValidate({ value, focused, allowEmpty = true }) { - // TODO: Re-run only after ~200ms of inactivity if (!value && allowEmpty) { return { valid: null,