【React】实现TagInput输入框,可以输入多个邮箱并校验是否合法

背景

需要实现一个类似Select组件的tags模式的输入框,输入一个邮箱后,回车,会显示成tag样式,也可以删除每一个tag。

实现

技术栈:react-tag-input-component + Antd

目前Antd没有提供现成的组件,可以使用react-tag-input-component,回车生成tag的时候进行校验邮箱是否合法,并显示错误提示

在进行表单提交的时候,也可以对tags进行非空和合法性校验。

EmailsFormInput/index.tsx:

javascript 复制代码
import { Form, FormItemProps } from 'antd';
import { forwardRef, useImperativeHandle, useState } from 'react';
import { TagsInput, TagsInputProps } from 'react-tag-input-component';
import styles from './index.module.less';

interface Props {
  formItemProps: FormItemProps;
  tagsInputProps: TagsInputProps;
}

const EmailErrorText = 'Please enter a valid email';
const EmailsEmptyErrorText = 'Please enter email';
const EmailReg = /^[\w.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(,[\w.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})*$/g;

export const EmailsFormInput = forwardRef(({ formItemProps, tagsInputProps }: Props, ref: any) => {
  const [emailErrorTip, setEmailErrorTip] = useState<string>('');

  const handleValidateEmail = (emails: string[]) => {
    // 必填
    if (!emails?.length) {
      setEmailErrorTip(EmailsEmptyErrorText);
      return false;
    }
    // 邮箱格式是否正确
    if (!emails?.every((e) => new RegExp(EmailReg).test(e))) {
      setEmailErrorTip(EmailErrorText);
      return false;
    }
    return true;
  };

  useImperativeHandle(ref, () => ({
    // 暴露对emails的校验方法
    handleValidateEmail,
  }));

  return (
    // validateStatus 和 help 用于错误提示
    <Form.Item {...formItemProps} help={emailErrorTip} validateStatus="error" className={styles.tagInputFormItem}>
      <div className={styles.tagInputContainer}>
        <TagsInput
          placeHolder="Input email and enter to add more"
          classNames={{ tag: styles.tagContainer, input: styles.inputContainer }}
          {...tagsInputProps}
          onKeyUp={(e) => {
            if (e.key === 'Backspace') {
              // 删除操作的时候,需要清空错误提示
              setEmailErrorTip('');
            }
          }}
          beforeAddValidate={(tag: string) => {
            // 添加tag前对输入的字符进行校验
            if (tag && new RegExp(EmailReg).test(tag)) {
              setEmailErrorTip('');
              return true;
            }
            setEmailErrorTip(EmailErrorText);
            return false;
          }}
        />
      </div>
    </Form.Item>
  );
});

EmailsFormInput/index.module.less: 修改ui以适应Antd的设计风格

css 复制代码
.tagInputFormItem {
  .tagInputContainer {
    div:first-child {
      padding: 1px 2px;
      --rti-main: rgb(36, 126, 252);
      border: 1px solid #ccc;
      min-height: 54px;
      display: flex;
      justify-content: flex-start;
      align-items: flex-start;
    }
  }
  .tagContainer {
    background-color: rgba(0, 0, 0, 0.06);
    margin: 2px 4px 2px 0;
    height: 24px;
    button {
      height: 10px;
      width: 10px;
      font-size: 10px;
      color: rgba(0, 0, 0, 0.45);
    }
  }

  .inputContainer {
    height: 28px;
    width: 40%;
    margin-left: 8px;
    color: rgba(0, 0, 0, 0.88);
  }
}

使用

javascript 复制代码
<EmailsFormInput
  formItemProps={{
    name: 'approver_list',
    label: 'Approver(s)',
    rules: [
      {
        required: true,
        message: 'Approver',
      },
    ],
  }}
  tagsInputProps={{ value: approvers, onChange: setApprovers }}
  ref={approverEmailInputRef}
/>


相关推荐
_阿南_14 小时前
项目中新增给AI制定的代码规范
前端·程序员
名字还没想好☜15 小时前
React 实现暗黑模式切换:localStorage 持久化、SSR 首屏闪烁与跟随系统主题
前端·javascript·react.js·ecmascript·react·next.js
自动化监测Learner16 小时前
主流 Web 端地图引擎对比:选型指南与优劣分析
javascript
console.log('npc')16 小时前
Git 冲突与 AI 协助指南
前端·人工智能·git·大模型
爱学堂IT分享17 小时前
Cesium可视化系统实战课程-Cesium教程学习
前端
糖墨夕18 小时前
理解大语言模型:Agent 的“大脑”
前端·agent
Rain的Java大神之路18 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
cpolar技术支持18 小时前
浏览器也能跑本地 AI:用 Transformers.js + WebGPU 做一个最小推理 Demo,cpolar 给同事远程体验
前端·ai·cpolar·webgpu·transformers.js
计算机魔术师20 小时前
OpenAI 发布 GPT-6 Astra:多项基准刷新纪录, cybersecurity 能力达 Critical 阈值
前端
xy345320 小时前
Axure9.0中继器遮罩实现方法
前端·ui·html·axure·原型·产品设计