1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
8 type CssRules = "formInputError";
10 const styles: StyleRulesCallback<CssRules> = theme => ({
18 type ValidatorProps = {
20 onChange: (isValid: boolean | string) => void;
21 render: (hasError: boolean) => React.ReactElement<any>;
25 interface ValidatorState {
26 isPatternValid: boolean;
27 isLengthValid: boolean;
30 const nameRegEx = /^[a-zA-Z0-9-_ ]+$/;
31 const maxInputLength = 60;
33 export const Validator = withStyles(styles)(
34 class extends React.Component<ValidatorProps & WithStyles<CssRules>> {
35 state: ValidatorState = {
40 componentWillReceiveProps(nextProps: ValidatorProps) {
41 const { value } = nextProps;
43 if (this.props.value !== value) {
45 isPatternValid: value.match(nameRegEx),
46 isLengthValid: value.length < maxInputLength
47 }, () => this.onChange());
52 const { value, onChange, isRequired } = this.props;
53 const { isPatternValid, isLengthValid } = this.state;
54 const isValid = value && isPatternValid && isLengthValid && (isRequired || (!isRequired && value.length > 0));
60 const { classes, isRequired, value } = this.props;
61 const { isPatternValid, isLengthValid } = this.state;
65 {this.props.render(!(isPatternValid && isLengthValid) && (isRequired || (!isRequired && value.length > 0)))}
66 {!isPatternValid && (isRequired || (!isRequired && value.length > 0)) ?
67 <span className={classes.formInputError}>This field allow only alphanumeric characters, dashes, spaces and underscores.<br/></span> : null}
69 <span className={classes.formInputError}>This field should have max 60 characters.</span> : null}