当前位置: 首页 > article >正文

NextJS开发:封装shadcn/ui中的AlertDialog确认对话框

shadcn/ui很灵活可以方便的自己修改class样式,但是仅仅一个确认删除弹窗,需要拷贝太多代码和导入太多包,重复的代码量太多,不利于代码维护。所以进一步封装以符合项目中使用。

封装cx-alert-dialog.tsx

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
import { CustomButton } from "./custom-button"

export const CxAlertDialog = (props: {
  visible: boolean, 
  title?: string, 
  content?: string, 
  cancelText?: string, 
  okText?: string,
  okColor?: string,
  loading?: boolean,
  disabled: boolean,
  onClose: ()=>void,
  onOk: ()=>void,
}) => {

  const buildOkButton = () => {
    if(props.okColor == "red") {
      return (
        <CustomButton variant="destructive" loading={props.loading} disabled={props.disabled} onClick={props.onOk}>{props.okText}</CustomButton>
      )
    }
    else {
      return (
        <CustomButton loading={props.loading} disabled={props.disabled} onClick={props.onOk}>{props.okText}</CustomButton>
      )
    }
  }

  return (
    <>
      <AlertDialog open={props.visible}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{props.title}</AlertDialogTitle>
            <AlertDialogDescription>
              {props.content}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={props.onClose} disabled={props.disabled}>{props.cancelText}</AlertDialogCancel>
            { buildOkButton() }
            {/* {
              props.okColor == "red"
              ?
              <AlertDialogAction className="bg-red-500 hover:bg-red-600" onClick={props.onOk}>{props.okText}</AlertDialogAction>
              :
              <AlertDialogAction onClick={props.onOk}>{props.okText}</AlertDialogAction>
            } */}
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}

custom-button.tsx

"use client"
import React, { MouseEventHandler } from "react";
import { Button } from "../ui/button";
import LcIcon from "./lc-icon";
import { cn } from "@/lib/utils";

/** 
 * Button扩展,增加图标功能 
 * <CustomButton icon="Loader" onClick={handleSubmit}>Button</CustomButton>
 * */
export const CustomButton = (props: {
  variant?: string,
  size?: string,
  className?: string,
  iconClassName?: string,
  icon?: string, 
  loading?: boolean
  disabled?: boolean,
  type?: string,
  onClick?: MouseEventHandler<HTMLButtonElement>,
  children?: any
}) => {

  const buildIcon = () => {
    if(props.loading != null && props.loading) {
      return <LcIcon name="Loader" size={16} className={cn("animate-spin", props.iconClassName ?? 'mr-1' )}/>
    }
    else if(props.icon != null) {
      return <LcIcon name={props.icon} size={16} className={props.iconClassName ?? 'mr-1'}/>
    }
    return ""
  }

  return (
    <Button size={props.size as any ?? "default"} variant={props.variant as any ?? "default"} type={props.type ?? 'button' as any} className={props.className} disabled={props.disabled} onClick={props.onClick}>
      { buildIcon() }
      { props.children }
    </Button>
  )
}

使用CxAlertDialog组件

const [delAlertVisible, setDelAlertVisible]:[boolean, Dispatch<SetStateAction<boolean>>] = React.useState(false);
  const [delAlertLoading, setDelAlertLoading]:[boolean, Dispatch<SetStateAction<boolean>>] = React.useState(false);
  const currOperId = useRef(BigInt(0))
  const handleDelAlertOk = async () => {
    setDelAlertLoading(true)
    await ChapterApi.del(Number(props.docId), currOperId.current).catch((e) => ErrUtils.apiHandle(e)).then((resp)=>{
      //console.log(resp)
      if(!resp) return
      if(resp?.code == RespCode.Success) {
        setDelAlertVisible(false)
        ToastUtils.success({ msg: resp?.msg })
        currChapterId.current = ""
        refresh()
      } else {
        ToastUtils.error({ msg: resp?.msg ?? "22" })
      }
    })
    .finally(()=>{
      setDelAlertLoading(false)
    })
  }

  const buildDel = () => {
    return (
      <CxAlertDialog visible={delAlertVisible} okColor="red" title="提示" content="确认删除?" cancelText="取消" okText="删除"
        onClose={() => setDelAlertVisible(false)} onOk={() => handleDelAlertOk()} loading={delAlertLoading} disabled={delAlertLoading}/>
    )
  }

http://www.kler.cn/news/149122.html

相关文章:

  • windows系统mobaxterm远程执行linux上ssh命令
  • 中伟视界:AI智能分析盒子的人数统计AI算法通过什么算法模型可以解决重复统计的问题?
  • 【AI考证笔记】NO.1人工智能的基础概念
  • Mysql更新Blob存储的Josn数据
  • c++调用openssl对文件加解密
  • ubuntu配置免密登录vscode
  • 如何优化 Elasticsearch 查询性能
  • 华为P40无法链接adb的解决记录
  • 深度学习之六(自编码器--Autoencoder)
  • 面向植保任务的无人机集群系统及其应用研究
  • shell编程系列(4)-循环结构
  • Java第十二篇:连接安全版kafka(Kerberos认证)出现的问题解答
  • C++学习之路(十)C++ 用Qt5实现一个工具箱(增加一个时间戳转换功能)- 示例代码拆分讲解
  • Matlab 点云曲率计算(之二)
  • 浅谈现代化城市建设中智慧消防的研究与应用
  • Python与微信交互(互动)神器yyds
  • 数字乡村:科技赋能农村产业升级
  • 计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(用户上传头像+用户收货管理)
  • 鸿运主动安全监控云平台存在任意文件读取漏洞 附POC
  • oracle免费资源 终止实例 以及新建一台实例的折腾记录
  • 【Linux进阶之路】进程间通信
  • ubuntu vmware开启3d加速画面异常
  • Unity 接入TapADN播放广告时闪退 LZ4JavaSafeCompressor
  • map出现遍历新数组undefined解决
  • C#鼠标穿透功能(WinForm)
  • 命令模式 (Command Pattern)
  • OPENWRT路由配置IPV6公网访问
  • PTA:用函数实现从数列中删除一个数
  • Redis深入理解-主从架构下内核数据结构、主从同步以及主节点选举
  • 微信小程序获取手机号流程以及用到的API