import React, { createRef } from 'react'; import Portal from '../Portal'; import type { ToastMethods, ToastOptions, ToastType } from './interface'; import { RemoveToast, Toast as JSToast } from './ToastProvider'; import Toast from './Toast'; type OptionsMap = Record; const parseOptions = (message: ToastOptions | string) => { if (typeof message === 'object') { return message; } return { message }; }; const defaultOptions: ToastOptions = { type: 'text', duration: 2000, message: '', position: 'middle', forbidPress: false, closeOnPressOverlay: false, overlay: false, loadingType: 'circular', }; let defaultOptionsMap = {} as OptionsMap; let currentOptions = { ...defaultOptions, }; const toastKeyMap: { [key: number]: 1 } = {}; export const remove = (key: number) => { Portal.remove(key); delete toastKeyMap[key]; RemoveToast(); }; export const removeAll = () => { Object.keys(toastKeyMap).forEach((_key) => { Portal.remove(Number.parseInt(_key, 10)); }); RemoveToast(); }; export const Instance = (options: ToastOptions | string) => { const op = parseOptions(options); const opts = { ...currentOptions, ...defaultOptionsMap[op.type || 'text'], ...op, }; const useJSToast = false; // TODO: 后续需要移除 JSToast 相关代码,待原生调研是否有更合适的方案 if (!useJSToast) { const ToastRef = createRef(); const key = Portal.add( { remove(key); // Portal.remove(key); opts.onClosed?.(); }} /> ); toastKeyMap[key] = 1; return { key, close: () => { ToastRef.current?.close(); }, setMessage: (m: string) => { ToastRef.current?.setMessage(m); }, }; } return JSToast({ ...currentOptions, ...defaultOptionsMap[op.type || 'text'], ...op, }); }; export const loading = (options: ToastOptions | string) => Instance({ type: 'loading', // loading默认禁止背景点击 forbidPress: true, ...parseOptions(options), }); export const success = (options: ToastOptions | string) => Instance({ type: 'success', ...parseOptions(options), }); export const fail = (options: ToastOptions | string) => Instance({ type: 'fail', ...parseOptions(options), }); export const warn = (options: ToastOptions | string) => Instance({ type: 'warn', ...parseOptions(options), }); /** * 修改默认配置,对所有 Toast 生效。传入 type 可以修改指定类型的默认配置 */ export const setDefaultOptions = ( type: ToastType | ToastOptions, options?: ToastOptions ) => { if (typeof type === 'string') { defaultOptionsMap[type] = options; } else { Object.assign(currentOptions, type); } }; /** * 重置默认配置,对所有 Toast 生效。传入 type 可以重置指定类型的默认配置 */ export const resetDefaultOptions = (type: ToastType | ToastOptions) => { if (typeof type === 'string') { defaultOptionsMap[type] = null; } else { currentOptions = { ...defaultOptions }; defaultOptionsMap = {} as OptionsMap; } };