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

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}/>
    )
  }

相关文章:

  • web静态网页设计与制作-基于HTML+CSS+JS实现旅游摄影网站
  • 强芯铸魂,生态共赢!麒麟信安出席2023龙芯产品发布暨用户大会
  • 【经验分享】开发问题记录总结(持续更新)
  • 机器学习-线性模型·
  • 蓝桥杯每日一题2023.11.28
  • 【微服务】java 规则引擎使用详解
  • 五子棋游戏
  • leetcode:用栈实现队列(先进先出)
  • 【深度学习】参数优化和训练技巧
  • pycharm编译报错处理
  • OpenGL的学习之路 -5
  • 基于SpringBoot房产销售系统
  • 指数退避和抖动
  • 网工内推 | 云计算运维,云相关认证优先,最高30K,带薪年假
  • 视频号小店需要多少资金?都需要准备什么东西?一篇详解!
  • Python与设计模式--门面模式
  • 03_MySQL基本SQL语句讲解
  • ClickHouse:真正的OLAP列式DBMS
  • 【迅搜04】索引配置(一)加载配置文件以及服务端配置
  • 【开源】基于Vue和SpringBoot的个人健康管理系统
  • 北京13日冰雹过后,已受理各险种报案近3万件
  • 风雨天涯梦——《袁保龄公牍》发微
  • 印称印巴军事行动总指挥同意将局势降级
  • 中美发布日内瓦经贸会谈联合声明达成关税共识,外交部回应
  • 淡马锡辟谣:淡马锡和太白投资未在中国销售任何投资产品或金融工具
  • 多元史料下的“西狩”叙事——《“庚子西狩”中外资料六种》解题