所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

React Toast组件Sonner使用详解

简介

Sonner 是 React 的一个 Toast 组件。
它支持多种类型的提示信息,如成功、错误、信息、警告和加载中,主题定义,可以在页面中显示提示信息。

安装

npm install sonner
# or
yarn add sonner

基本使用

Toaster app.jsx 里,也可以放在 layout.jsx 布局文件里,这样全局都可以使用

import { Toaster } from "sonner";

function App() {
  return (
    <div className="App">
      <Toaster />
    </div>
  );
}

export default App;

这样组件或者页面,都可以直接使用 toast 方法了

import { toast } from "sonner";

toast.success("Success message");
toast.error("Error message");
toast.info("Info message");
toast.warning("Warning message");
toast.loading("Loading message");

‘top’,’right’ | ‘bottom’ | ‘left’

Sonner 参数

参数说明类型默认值可选值
position位置stringtop-righttop-left’,’top-right’,’bottom-left’,’bottom-right’,’top-center’
duration持续时间number4000
theme主题string‘ligth‘light,dark,system’
offset偏移量string,number,object32px
mobileOffset移动端偏移量string,number,object16px
expanded是否展开booleanfalsetrue,false
richColors是否显示彩色booleanfalsetrue,false
visibleToasts显示的 toast 数量number3
closeButton是否显示关闭按钮booleanfalsetrue,false
direction方向string‘ltr’‘ltr’,’rtl’
swipeDirections滑动方向string‘up’‘up’,’down’
hotkeys快捷键booleanfalsetrue,false
invert是否反转booleanfalsetrue,false
toastOptionstoast 选项object{}
gap间距number16px
icons自定义图标objectobject

Sonner 示例

toastOptions 设置

import { Toaster } from "sonner";

function App() {
  return (
    <div className="App">
      <Toaster
        toastOptions={{
          style: {
            background: "red",
          },
          className: "my-toast",
          classNames: {
            toast: "my-toast",
            icon: "my-icon",
            message: "my-message",
          },
          descriptionClassName: "my-description",
          cancelButtonStyle: React.CSSProperties,
          actionButtonStyle: React.CSSProperties,
        }}
      />
    </div>
  );
}

export default App;

更多参数配置,请往下参考 toast 方法参数

icons 自定义

import { Toaster } from "sonner";

function App() {
  return (
    <div className="App">
      <Toaster
        icons={{
          success: <CheckCircle />,
          error: <XCircle />,
          warning: <ExclamationCircle />,
          info: <InfoCircle />,
          loading: <Spinner />,
        }}
      />
    </div>
  );
}

export default App;

toast 参数

参数说明类型默认值可选值
description描述string
icon图标ReactNode
duration持续时间number4000
position位置stringtop-righttop-left’,’top-right’,’bottom-left’,’bottom-right’,’top-center’
closeButton是否显示关闭按钮booleanfalsetrue,false
invert是否反转booleanfalsetrue,false
dismissible是否可手动关闭booleantruetrue,false
action确认按钮ReactNode
cancelButton取消按钮ReactNode
id唯一标识numberstring
onDismiss关闭回调函数function()=>{}
onAutoClass超时自动关闭回调函数function()=>{}
containerAriaLabel容器 aria 标签string
actionButtonStyle确认按钮样式object
cancelButtonStyle取消按钮样式object

toast 示例

更新 toast

import { toast } from "sonner";

function Demo() {
  const updateToast = () => {
    const toastId = toast("Sonner");
    setTimeout(() => {
      toast("updateed toast", {
        id: toastId,
      });
    }, 3000);
  };

  return (
    <div className="demo">
      <button onClick={updateToast}>Update Toast</button>
    </div>
  );
}

export default App;

自定义 Toast 关闭倒计时显示

useCountdown.js

import { useState, useEffect, useCallback } from "react";

/**
 * 倒计时 Hook
 * @param initialSeconds 初始倒计时秒数
 * @param onEnd 倒计时结束回调
 * @returns [剩余秒数, 重启倒计时函数]
 */
export function useCountdown(initialSeconds, onEnd) {
  const [seconds, setSeconds] = useState(initialSeconds);

  // 重启倒计时
  const restart = useCallback(
    (newSeconds) => {
      // 允许动态修改初始时间,默认使用原始初始值
      setSeconds(newSeconds ?? initialSeconds);
    },
    [initialSeconds]
  );

  useEffect(() => {
    if (seconds <= 0) {
      onEnd?.();
      return;
    }

    const timer = setInterval(() => {
      setSeconds((prev) => {
        if (prev <= 1) {
          clearInterval(timer);
          onEnd?.();
          return 0;
        }
        return prev - 1;
      });
    }, 1000);

    return () => clearInterval(timer);
  }, [seconds, onEnd]);

  return [seconds, restart];
}

EasySonner.jsx

import { toast } from "sonner";
import { useCountdown } from "useCountdown";

export default function EasySonner({
  initialSeconds = 4,
  message,
  isCountdown = true,
  isClose = true,
}) {
  const [seconds] = useCountdown(initialSeconds, () => {
    toast.dismiss();
  });

  return (
    <div className="flex w-full items-center justify-between">
      <div className="flex-1 items-center flex gap-2">
        {isClose && (
          <i
            className="inline-block h-[max-content] w-[max-content] sysicon sysicon-alert-error text-field-error text-[14px]"
            onClick={() => {
              toast.dismiss();
            }}
          ></i>
        )}
        {message}
      </div>
      {isCountdown && <div>{seconds}s</div>}
    </div>
  );
}

使用

import { toast } from "sonner";
import EasySonner from "EasySonner";

const duration = 10; // 10秒
const promise = new Promise((resolve) => {
  setTimeout(resolve, 1000 * duration); // 模拟异步操作
});

toast.promise(promise, {
  duration: 1000 * duration,
  icon: null, // 不显示loading图标
  loading: (
    <EasySonner
      initialSeconds={duration}
      message="Please agree"
      isCountdown={true}
      isClose={true}
    />
  ),
});

参数

参数说明类型默认值
initialSeconds初始秒数number4
message提示内容string
isCountdown是否倒计时booleantrue
isClose是否显示关闭按钮booleantrue
原文链接:https://code.ifrontend.net/archives/329,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?