diff --git a/src/packages/dialog/config.ts b/src/packages/dialog/config.ts index 01b3d24fd8..e95a03ca94 100644 --- a/src/packages/dialog/config.ts +++ b/src/packages/dialog/config.ts @@ -26,6 +26,7 @@ export interface BasicDialogProps { onConfirm?: (e?: MouseEvent) => Promise<() => void> | void onCancel?: () => void onClick?: () => void + onOverlayClick?: () => void } export type DialogReturnProps = { diff --git a/src/packages/dialog/content.taro.tsx b/src/packages/dialog/content.taro.tsx index 17fc1d1a15..c83b465e99 100644 --- a/src/packages/dialog/content.taro.tsx +++ b/src/packages/dialog/content.taro.tsx @@ -11,7 +11,8 @@ interface ContentProps { } export const Content: FunctionComponent< - Partial & Omit, 'onClick'> + Partial & + Omit, 'onClick' | 'title'> > = (props) => { const { visible, title, footer, footerDirection, onClick, children } = props diff --git a/src/packages/dialog/demo.taro.tsx b/src/packages/dialog/demo.taro.tsx index 3f45133823..4826834f33 100644 --- a/src/packages/dialog/demo.taro.tsx +++ b/src/packages/dialog/demo.taro.tsx @@ -63,6 +63,22 @@ const DialogDemo = () => { <>
+

函数调用

+ + + Dialog.open('test', { + title: 'ok?', + onConfirm: () => { + Dialog.close('test') + }, + onCancel: () => { + Dialog.close('test') + }, + }) + } + />

{translated.title1}

setVisible1(true)} /> true, beforeClose: () => true, + onOverlayClick: () => undefined, } as DialogProps -export const BaseDialog = forwardRef( - ( - props: Partial & - Omit< - React.HTMLAttributes, - 'title' | 'content' | 'onClick' - >, - ref - ) => { - const { locale } = useConfig() - const { +export const BaseDialog: FunctionComponent> & { + open: typeof open + close: typeof close +} = (props) => { + const classPrefix = 'nut-dialog' + const { locale } = useConfig() + + const { + params: { + id, visible, footer, + title, + footerDirection, hideConfirmButton, hideCancelButton, lockScroll, disableConfirmButton, closeOnOverlayClick, + onOverlayClick, confirmText, cancelText, + overlay, onClose, onCancel, onConfirm, beforeCancel, beforeClose, - ...restProps - } = props - const classPrefix = 'nut-dialog' - - const renderFooter = () => { - if (footer === null) return '' + }, + setParams, + } = useParams({ ...defaultProps, ...props }) - const handleCancel = (e: MouseEvent) => { - e.stopPropagation() - if (!beforeCancel?.()) return - if (!beforeClose?.()) return - onClose?.() - onCancel?.() + useCustomEvent( + id as string, + ({ status, options }: { status: boolean; options: any }) => { + if (status) { + setParams({ ...options, visible: true }) + } else { + setParams({ ...options, visible: false }) } + } + ) - const handleOk = (e: MouseEvent) => { - e.stopPropagation() - onClose?.() - onConfirm?.(e) - } + const renderFooter = () => { + if (footer === null) return '' - return ( - footer || ( - <> - {!hideCancelButton && ( - - )} - {!hideConfirmButton && ( - - )} - - ) - ) + const handleCancel = (e: MouseEvent) => { + e.stopPropagation() + if (!beforeCancel?.()) return + if (!beforeClose?.()) return + onClose?.() + onCancel?.() } + const handleOk = (e: MouseEvent) => { + e.stopPropagation() + onClose?.() + onConfirm?.(e) + } return ( - - - + footer || ( + <> + {!hideCancelButton && ( + + )} + {!hideConfirmButton && ( + + )} + + ) ) } -) + const onHandleClickOverlay = (e: any) => { + console.log('onClose?.()', closeOnOverlayClick) + if (closeOnOverlayClick && visible && e.target === e.currentTarget) { + const closed = onOverlayClick && onOverlayClick() + closed && onClose?.() + closed && onCancel?.() + } + } + console.log('props', props, visible) + + return ( + + <> + {overlay ? ( + + ) : null} + + + + + + + ) +} + +export function open(selector: string, options: Partial) { + // eslint-disable-next-line react-hooks/rules-of-hooks + const path = useCustomEventsPath(selector) + customEvents.trigger(path, { status: true, options }) +} + +export function close(selector: string) { + // eslint-disable-next-line react-hooks/rules-of-hooks + const path = useCustomEventsPath(selector) + customEvents.trigger(path, { status: false }) +} BaseDialog.defaultProps = defaultProps BaseDialog.displayName = 'NutDialog' +BaseDialog.open = open +BaseDialog.close = close diff --git a/src/packages/dialog/doc.taro.md b/src/packages/dialog/doc.taro.md index 53a0cb0a66..207b937bb5 100644 --- a/src/packages/dialog/doc.taro.md +++ b/src/packages/dialog/doc.taro.md @@ -14,6 +14,41 @@ import { Dialog } from '@nutui/nutui-react-taro' ## 代码演示 +### 函数调用 +:::demo + +```tsx +import React, {useState} from "react"; +import { Cell,Dialog } from '@nutui/nutui-react-taro'; + +const App = () => { + + return ( + <> + + + Dialog.open('test', { + title: 'ok?', + onConfirm: () => { + Dialog.close('test') + }, + onCancel: () => { + Dialog.close('test') + }, + }) + } + /> + + ) +} +export default App; +``` + +::: + + ### 组件调用 :::demo @@ -148,6 +183,14 @@ export default App; | onClick | 点击自身回调 | `() => void` | `-` | | onOverlayClick | 点击蒙层触发 | `() => void` | `-` | +### Methods +| 方法名 | 说明 | 类型 | +| --- | --- | --- | +| Dialog.open | 打开 Dialog | (id: string, options: DialogOptions) => void | +| Dialog.close | 关闭 Dialog | (id: string) => void | + +DialogOptions 是 DialogProps 的子集,包含如下属性:title, content, footer, confirmText, cancelText, overlay, closeOnOverlayClick, hideConfirmButton, hideCancelButton, disableConfirmButton, footerDirection, lockScroll, beforeCancel, beforeClose, onOverlayClick, + ## 主题定制 ### 样式变量 diff --git a/src/packages/toast/doc.taro.md b/src/packages/toast/doc.taro.md index 2c92ea258d..3d1d992acd 100644 --- a/src/packages/toast/doc.taro.md +++ b/src/packages/toast/doc.taro.md @@ -199,13 +199,14 @@ export default App | visible | 弹窗是否显示开关 | `boolean` | `false` | | onClose | 关闭时触发的事件 | `Function` | `null` | -### ToastOptions -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| msg | 消息文本内容,支持传入HTML | `string \| VNode` | `-` | -| duration | 展示时长(秒),值为 0 时,toast 不会自动消失(loading类型默认为0) | `number` | `2` | -| title | 标题 | `string` | `-` | -| type | 弹框类型 可选值(text、success、fail、warn、loading) | `string` | `-` | +### Methods +| 方法名 | 说明 | 类型 | +| --- | --- | --- | +| Toast.show | 打开 Toast | (id: string, options: ToastOptions) => void | +| Toast.hide | 关闭 Toast | (id: string) => void | + +ToastOptions 是 ToastProps 的子集,包含如下属性:msg, title, type, duration + ## 主题定制 diff --git a/src/utils/use-custom-event.ts b/src/utils/use-custom-event.ts index fb7f5d70da..d7881acc46 100644 --- a/src/utils/use-custom-event.ts +++ b/src/utils/use-custom-event.ts @@ -1,4 +1,5 @@ import { useEffect, useRef } from 'react' +import isEqual from 'lodash.isequal' import { Events, getCurrentInstance } from '@tarojs/taro' import { useForceUpdate } from '@/utils/use-force-update' @@ -28,11 +29,22 @@ export function useCustomEvent(selector: string, cb: any) { export function useParams(args: T) { const forceUpdate = useForceUpdate() - const pRef = useRef(args) + const stateRef = useRef(args) + + const currentRef = useRef() + const previousRef = useRef() + + if (!isEqual(currentRef.current, args)) { + previousRef.current = currentRef.current + currentRef.current = args + stateRef.current = args + } + const setParams = (args: T) => { - pRef.current = { ...pRef.current, ...args } + stateRef.current = { ...stateRef.current, ...args } forceUpdate() } - const params = pRef.current + + const params = stateRef.current return { params, setParams } }