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"
              ?
              {props.okText}
              :
              {props.okText}
            } */}
          </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扩展,增加图标功能 
 * Button
 * */
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}/>
    )
  }

你可能感兴趣的:(NextJS开发教程,nextjs,typescript,react.js)