errorMessage.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* eslint-disable prefer-template */
  2. import React, { PureComponent } from 'react';
  3. import classNames from 'classnames';
  4. import PropTypes from 'prop-types';
  5. import { cssClasses } from '@douyinfe/semi-foundation/form/constants';
  6. import { IconAlertTriangle, IconAlertCircle } from '@douyinfe/semi-icons';
  7. const prefix = cssClasses.PREFIX;
  8. export type ReactFieldError = boolean | string | Array<any> | React.ReactNode | undefined;
  9. export interface ErrorMessageProps {
  10. error?: ReactFieldError;
  11. className?: string;
  12. style?: React.CSSProperties;
  13. showValidateIcon?: boolean;
  14. validateStatus?: string;
  15. helpText?: React.ReactNode;
  16. isInInputGroup?: boolean;
  17. }
  18. export default class ErrorMessage extends PureComponent<ErrorMessageProps> {
  19. static propTypes = {
  20. error: PropTypes.oneOfType([PropTypes.bool, PropTypes.string, PropTypes.array, PropTypes.node]),
  21. className: PropTypes.string,
  22. style: PropTypes.object,
  23. validateStatus: PropTypes.string,
  24. showValidateIcon: PropTypes.bool,
  25. helpText: PropTypes.node,
  26. isInInputGroup: PropTypes.bool,
  27. };
  28. generatorText(error: ReactFieldError) {
  29. if (typeof error === 'string') {
  30. return <span>{error}</span>;
  31. } else if (Array.isArray(error)) {
  32. const err = error.filter(e => e);
  33. return err.length ? <span>{err.join(', ')}</span> : null;
  34. } else if (React.isValidElement(error)) {
  35. return error;
  36. }
  37. return null;
  38. }
  39. render() {
  40. const { error, className, style, validateStatus, helpText, showValidateIcon, isInInputGroup } = this.props;
  41. const cls = classNames(
  42. {
  43. [prefix + '-field-error-message']: Boolean(error),
  44. [prefix + '-field-help-text']: Boolean(helpText),
  45. },
  46. className
  47. );
  48. if (!error && !helpText) {
  49. return null;
  50. }
  51. const iconMap = {
  52. warning: <IconAlertTriangle />,
  53. error: <IconAlertCircle />,
  54. };
  55. const text = error ? this.generatorText(error) : this.generatorText(helpText);
  56. const iconCls = `${prefix }-field-validate-status-icon`;
  57. let icon = null;
  58. if (isInInputGroup) {
  59. icon = <IconAlertCircle className={iconCls} />;
  60. } else {
  61. if (iconMap[validateStatus]) {
  62. icon = React.cloneElement(iconMap[validateStatus], { className: iconCls });
  63. }
  64. }
  65. return (
  66. <div className={cls} style={style}>
  67. {showValidateIcon && text ? icon : null}
  68. {text}
  69. </div>
  70. );
  71. }
  72. }