Input.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import React, { PureComponent } from 'react';
  2. import { ValidationRule } from 'app/types';
  3. export enum InputStatus {
  4. Default = 'default',
  5. Loading = 'loading',
  6. Invalid = 'invalid',
  7. Valid = 'valid',
  8. }
  9. export enum InputTypes {
  10. Text = 'text',
  11. Number = 'number',
  12. Password = 'password',
  13. Email = 'email',
  14. }
  15. interface Props {
  16. status?: InputStatus;
  17. validationRules: ValidationRule[];
  18. hideErrorMessage?: boolean;
  19. onBlurWithStatus?: (evt, status: InputStatus) => void;
  20. emptyToNull?: boolean;
  21. }
  22. const validator = (value: string, validationRules: ValidationRule[]) => {
  23. const errors = validationRules.reduce((acc, currRule) => {
  24. if (!currRule.rule(value)) {
  25. return acc.concat(currRule.errorMessage);
  26. }
  27. return acc;
  28. }, []);
  29. return errors.length > 0 ? errors : null;
  30. };
  31. export class Input extends PureComponent<Props & React.HTMLProps<HTMLInputElement>> {
  32. state = {
  33. error: null,
  34. };
  35. get status() {
  36. const { error } = this.state;
  37. if (error) {
  38. return InputStatus.Invalid;
  39. }
  40. return InputStatus.Valid;
  41. }
  42. onBlurWithValidation = evt => {
  43. const { validationRules, onBlurWithStatus, onBlur } = this.props;
  44. let errors = null;
  45. if (validationRules) {
  46. errors = validator(evt.currentTarget.value, validationRules);
  47. this.setState(prevState => {
  48. return {
  49. ...prevState,
  50. error: errors ? errors[0] : null,
  51. };
  52. });
  53. }
  54. if (onBlurWithStatus) {
  55. onBlurWithStatus(evt, errors ? InputStatus.Invalid : InputStatus.Valid);
  56. }
  57. if (onBlur) {
  58. onBlur(evt);
  59. }
  60. };
  61. render() {
  62. const {
  63. status,
  64. validationRules,
  65. onBlurWithStatus,
  66. onBlur,
  67. className,
  68. hideErrorMessage,
  69. emptyToNull,
  70. ...restProps
  71. } = this.props;
  72. const { error } = this.state;
  73. let inputClassName = 'gf-form-input';
  74. inputClassName = this.status === InputStatus.Invalid ? inputClassName + ' invalid' : inputClassName;
  75. return (
  76. <div className="our-custom-wrapper-class">
  77. <input {...restProps} onBlur={this.onBlurWithValidation} className={inputClassName} />
  78. {error && !hideErrorMessage && <span>{error}</span>}
  79. </div>
  80. );
  81. }
  82. }