美文网首页
NextJS开发:封装shadcn/ui中的AlertDialo

NextJS开发:封装shadcn/ui中的AlertDialo

作者: ArslanRobot | 来源:发表于2023-11-27 12:45 被阅读0次

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

    相关文章

      网友评论

          本文标题:NextJS开发:封装shadcn/ui中的AlertDialo

          本文链接:https://www.haomeiwen.com/subject/zabzwdtx.html