diff --git a/src/packages/dialog/confirm.tsx b/src/packages/dialog/confirm.tsx index f358b3057c..a466a09d86 100644 --- a/src/packages/dialog/confirm.tsx +++ b/src/packages/dialog/confirm.tsx @@ -1,9 +1,9 @@ import React from 'react' import { Dialog } from './dialog' -import { destroyList, DialogConfirmProps, DialogReturnProps } from './types' +import { destroyList, BaseDialog, DialogReturnProps } from '@/types' import { render as reactRender, unmount } from '@/utils/render' -type DialogConfirmNativeProps = Partial +type DialogConfirmNativeProps = Partial function ConfirmDialog(props: DialogConfirmNativeProps) { return {props.content} } diff --git a/src/packages/dialog/content.taro.tsx b/src/packages/dialog/content.taro.tsx index c065a72777..864e82d97a 100644 --- a/src/packages/dialog/content.taro.tsx +++ b/src/packages/dialog/content.taro.tsx @@ -1,9 +1,9 @@ import React, { FunctionComponent, HTMLAttributes } from 'react' import classNames from 'classnames' import { View, ITouchEvent } from '@tarojs/components' -import { ContentProps } from './types.taro' +import { TaroContentProps } from '@/types' -export const defaultContentProps: ContentProps = { +export const defaultContentProps = { visible: false, title: '', header: '', @@ -14,7 +14,7 @@ export const defaultContentProps: ContentProps = { } export const Content: FunctionComponent< - Partial & + Partial & Omit, 'onClick' | 'title'> > = (props) => { const { @@ -25,6 +25,8 @@ export const Content: FunctionComponent< close, footerDirection, children, + style, + className, onClick, } = { ...defaultContentProps, ...props } @@ -49,13 +51,13 @@ export const Content: FunctionComponent< } const handleClick = (e: ITouchEvent) => { - onClick && onClick(e) + onClick(e) } return ( handleClick(e)} > {close} diff --git a/src/packages/dialog/content.tsx b/src/packages/dialog/content.tsx index 4e07c57543..8944de22ff 100644 --- a/src/packages/dialog/content.tsx +++ b/src/packages/dialog/content.tsx @@ -1,8 +1,8 @@ -import React, { FunctionComponent, HTMLAttributes } from 'react' +import React, { FunctionComponent, HTMLAttributes, MouseEvent } from 'react' import classNames from 'classnames' -import { ContentProps } from './types' +import { WebContentProps } from '@/types' -export const defaultContentProps: ContentProps = { +export const defaultContentProps = { visible: false, title: '', header: '', @@ -13,7 +13,7 @@ export const defaultContentProps: ContentProps = { } export const Content: FunctionComponent< - Partial & + Partial & Omit, 'title' | 'content'> > = (props) => { const { @@ -49,7 +49,7 @@ export const Content: FunctionComponent< ) } - const handleClick = (e: React.MouseEvent) => { + const handleClick = (e: MouseEvent) => { onClick && onClick(e) } diff --git a/src/packages/dialog/dialog.taro.tsx b/src/packages/dialog/dialog.taro.tsx index e5c26ac1e0..84a95da84e 100644 --- a/src/packages/dialog/dialog.taro.tsx +++ b/src/packages/dialog/dialog.taro.tsx @@ -1,13 +1,14 @@ -import React, { FunctionComponent, useState } from 'react' +import React, { FunctionComponent, useState, MouseEvent } from 'react' import classNames from 'classnames' import { CSSTransition } from 'react-transition-group' import { View, ITouchEvent } from '@tarojs/components' import { Failure, Close } from '@nutui/icons-react-taro' import Button from '@/packages/button/index.taro' -import { DialogBasicProps } from './types.taro' +import { TaroDialogProps } from '@/types' import { Content, defaultContentProps } from './content.taro' import { useConfig } from '@/packages/configprovider/configprovider.taro' import Overlay from '@/packages/overlay/index.taro' +import { defaultOverlayProps } from '@/packages/overlay/overlay.taro' import { customEvents, useCustomEvent, @@ -16,10 +17,9 @@ import { } from '@/hooks/use-custom-event' import { useLockScrollTaro } from '@/hooks/use-lock-scoll-taro' import { mergeProps } from '@/utils/merge-props' -import { defaultOverlayProps } from '@/packages/overlay/overlay.taro' import { harmony } from '@/utils/platform-taro' -const defaultProps: DialogBasicProps = { +const defaultProps = { ...defaultOverlayProps, ...defaultContentProps, title: '', @@ -28,55 +28,52 @@ const defaultProps: DialogBasicProps = { footer: '', confirmText: '', cancelText: '', - overlay: true, - overlayStyle: {}, - overlayClassName: 'nut-dialog-overlay', hideConfirmButton: false, hideCancelButton: false, disableConfirmButton: false, footerDirection: 'horizontal', closeIconPosition: 'bottom', closeIcon: false, + overlay: true, + overlayStyle: {}, + overlayClassName: 'nut-dialog-overlay', zIndex: 1200, beforeCancel: () => true, beforeClose: () => true, onCancel: () => {}, onClose: () => {}, + onConfirm: () => {}, onOverlayClick: () => true, } -export const BaseDialog: FunctionComponent> & { +export const BaseDialog: FunctionComponent> & { open: typeof open close: typeof close } = (props) => { - const classPrefix = 'nut-dialog' - const { locale } = useConfig() - const [loading, setLoading] = useState(false) - const { params: { id, + closeOnOverlayClick, + confirmText, + cancelText, + children, className, - style, - visible, - footer, - title, - header, + closeIconPosition, + closeIcon, content, - children, + disableConfirmButton, + footer, footerDirection, + header, hideConfirmButton, hideCancelButton, lockScroll, - disableConfirmButton, - closeOnOverlayClick, - confirmText, - cancelText, overlay, overlayStyle, overlayClassName, - closeIconPosition, - closeIcon, + style, + title, + visible, zIndex, beforeCancel, beforeClose, @@ -87,6 +84,9 @@ export const BaseDialog: FunctionComponent> & { }, setParams, } = useParams(mergeProps(defaultProps, props)) + const classPrefix = 'nut-dialog' + const { locale } = useConfig() + const [loading, setLoading] = useState(false) useCustomEvent( id as string, @@ -98,23 +98,21 @@ export const BaseDialog: FunctionComponent> & { const renderFooter = () => { if (footer === null) return '' - const handleCancel = ( - e: ITouchEvent | React.MouseEvent - ) => { + const handleCancel = (e: ITouchEvent | MouseEvent) => { e.stopPropagation() if (!beforeCancel?.()) return if (!beforeClose?.()) return - onClose?.() - onCancel?.() + onClose() + onCancel() } - const handleOk = async (e: React.MouseEvent) => { + const handleOk = async (e: MouseEvent) => { e.stopPropagation() setLoading(true) try { await onConfirm?.(e) setLoading(false) - onClose?.() + onClose() } catch { setLoading(false) } @@ -128,7 +126,7 @@ export const BaseDialog: FunctionComponent> & { !hideCancelButton && ( handleCancel(e)} + onClick={(e) => handleCancel(e)} > {cancelText || locale.cancel} @@ -143,9 +141,7 @@ export const BaseDialog: FunctionComponent> & { type="default" size="large" className={`${classPrefix}-footer-cancel ${btnClass}`} - onClick={(e: React.MouseEvent) => - handleCancel(e) - } + onClick={(e) => handleCancel(e)} > {cancelText || locale.cancel} @@ -157,13 +153,13 @@ export const BaseDialog: FunctionComponent> & { return ( !hideConfirmButton && ( + ) + ) + } + + const renderConfirm = () => { + return ( + !hideConfirmButton && ( + + ) + ) + } + return ( footer || ( <> - {!hideCancelButton && - (footerDirection === 'vertical' ? ( -
handleCancel(e)} - > - {cancelText || locale.cancel} -
- ) : ( - - ))} - {!hideConfirmButton && ( - + {footerDirection === 'vertical' ? ( + <> + {renderConfirm()} + {renderCancelOfVertical()} + + ) : ( + <> + {renderCancel()} + {renderConfirm()} + )} ) @@ -133,8 +182,8 @@ const BaseDialog: ForwardRefRenderFunction< const handleCancel = () => { if (!beforeCancel?.()) return if (!beforeClose?.()) return - onClose?.() - onCancel?.() + onClose() + onCancel() } const closeClasses = classNames({ [`${classPrefix}-close`]: true, @@ -148,33 +197,66 @@ const BaseDialog: ForwardRefRenderFunction< ) } + const onHandleClickOverlay = (e: MouseEvent) => { + if (closeOnOverlayClick && visible && e.target === e.currentTarget) { + const closed = onOverlayClick && onOverlayClick(e) + closed && onClose() + closed && onCancel() + } + } + + const renderContent = () => { + return ( + + + {content || children} + + + ) + } + return (
- + {overlay && ( + + )} + {renderContent()}
) } export const Dialog: DialogComponent = forwardRef(BaseDialog) as DialogComponent -Dialog.confirm = (props: Partial): DialogReturnProps => { +Dialog.confirm = (props: Partial): DialogReturnProps => { return confirm(props) } -;['alert'].forEach((type) => { - ;(Dialog as any)[type] = (props: Partial) => { +;['alert'].forEach(() => { + ;(Dialog as any).alert = (props: Partial) => { return confirm({ ...props, - isNotice: false, - noticeType: type, }) } }) diff --git a/src/packages/dialog/dialogwrap.tsx b/src/packages/dialog/dialogwrap.tsx deleted file mode 100644 index ff911faa19..0000000000 --- a/src/packages/dialog/dialogwrap.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React, { FunctionComponent, HTMLAttributes } from 'react' -import { CSSTransition } from 'react-transition-group' -import { Content, defaultContentProps } from './content' -import { defaultOverlayProps } from '@/packages/overlay/overlay' -import Overlay from '@/packages/overlay' -import { DialogWrapProps } from './types' - -export const defaultDialogWrapProps: DialogWrapProps = { - ...defaultOverlayProps, - ...defaultContentProps, - overlay: true, - overlayStyle: {}, - overlayClassName: 'nut-dialog-overlay', - onCancel: () => {}, - onClose: () => {}, - onOverlayClick: () => true, -} - -export const DialogWrap: FunctionComponent< - Partial & - Omit, 'title' | 'content'> -> = (props) => { - const { - visible, - overlay, - overlayStyle, - overlayClassName, - closeOnOverlayClick, - lockScroll, - zIndex, - onClose, - onCancel, - onOverlayClick, - ...restProps - } = { ...defaultDialogWrapProps, ...props } - - const onHandleClickOverlay = (e: React.MouseEvent) => { - if (closeOnOverlayClick && visible && e.target === e.currentTarget) { - const closed = onOverlayClick && onOverlayClick(e) - closed && onClose?.() - closed && onCancel?.() - } - } - return ( - <> - {overlay && ( - - )} - - - - - - ) -} -DialogWrap.displayName = 'NutDialogWrap' diff --git a/src/packages/dialog/index.taro.ts b/src/packages/dialog/index.taro.ts index 5cb92e397a..45349e2e70 100644 --- a/src/packages/dialog/index.taro.ts +++ b/src/packages/dialog/index.taro.ts @@ -4,11 +4,10 @@ export type { DialogConfigType, DialogCloseIconPosition, DialogFooterDirection, - ContentProps, + TaroContentProps as ContentProps, DialogWrapProps, - DialogBasicProps, - DialogConfirmProps, + TaroDialogProps as DialogProps, DialogReturnProps, -} from './types.taro' +} from '@/types' export default BaseDialog diff --git a/src/packages/dialog/index.ts b/src/packages/dialog/index.ts index c5c9160314..2b65c703e3 100644 --- a/src/packages/dialog/index.ts +++ b/src/packages/dialog/index.ts @@ -4,11 +4,10 @@ export type { DialogConfigType, DialogCloseIconPosition, DialogFooterDirection, - ContentProps, + WebContentProps as ContentProps, DialogWrapProps, - DialogBasicProps, - DialogConfirmProps, + WebDialogProps as DialogProps, DialogReturnProps, -} from './types' +} from '@/types' export default Dialog diff --git a/src/packages/dialog/types.taro.ts b/src/packages/dialog/types.taro.ts deleted file mode 100644 index 291824a145..0000000000 --- a/src/packages/dialog/types.taro.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ITouchEvent } from '@tarojs/components' - -import { - ContentProps as ContentWebProps, - DialogBasicProps as DialogBasicWebProps, -} from './types' - -export type { - DialogConfigType, - DialogCloseIconPosition, - DialogFooterDirection, - DialogWrapProps, - DialogConfirmProps, - DialogReturnProps, -} from './types' - -export type ContentProps = Omit & { - onClick: (event: ITouchEvent) => void -} - -export type DialogBasicProps = Omit< - DialogBasicWebProps, - 'onOverlayClick' | 'onClick' -> & { - onClick: (event: ITouchEvent) => void - onOverlayClick: (event: ITouchEvent) => boolean | void -} diff --git a/src/packages/dialog/types.ts b/src/packages/dialog/types.ts deleted file mode 100644 index cb1c697a0a..0000000000 --- a/src/packages/dialog/types.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ReactNode, ForwardRefExoticComponent, PropsWithChildren } from 'react' -import type { MouseEvent, CSSProperties } from 'react' -import { WebOverlayProps } from '@/types' -import { BasicComponent } from '@/utils/typings' - -export type DialogConfigType = { - prefixCls?: string - simple?: boolean -} - -export type DialogCloseIconPosition = 'top-right' | 'top-left' | 'bottom' -export type DialogFooterDirection = 'horizontal' | 'vertical' -export interface ContentProps extends BasicComponent { - visible: boolean - title: ReactNode - header: ReactNode - footer: ReactNode - close: ReactNode - footerDirection: DialogFooterDirection - onClick: (event: MouseEvent) => void -} -export interface DialogWrapProps - extends WebOverlayProps, - Omit { - visible: boolean - overlay: boolean - overlayStyle: CSSProperties - overlayClassName: string - onCancel: () => void - onClose: () => void - onOverlayClick: (e: MouseEvent) => boolean | void -} - -export interface DialogBasicProps extends DialogWrapProps { - content?: ReactNode - confirmText?: ReactNode - cancelText?: ReactNode - hideConfirmButton?: boolean - hideCancelButton?: boolean - disableConfirmButton?: boolean - closeIconPosition?: DialogCloseIconPosition - closeIcon?: boolean | ReactNode - beforeClose?: () => boolean - beforeCancel?: () => boolean - onConfirm?: (e?: MouseEvent) => PromiseLike | void -} - -export interface DialogConfirmProps extends DialogBasicProps { - content: ReactNode - isNotice: boolean - noticeType: string -} - -export type DialogReturnProps = { - update: (newConfig: Partial) => void - close: () => void -} - -export interface DialogComponent - extends ForwardRefExoticComponent< - PropsWithChildren> - > { - confirm: (props: Partial) => DialogReturnProps - alert: (props: Partial) => DialogReturnProps - config: (config: DialogConfigType) => void - destroyAll: () => void -} - -export const destroyList: Array<() => void> = [] diff --git a/src/types/spec/dialog/base.ts b/src/types/spec/dialog/base.ts index a21fb9bbea..2410a2c3f6 100644 --- a/src/types/spec/dialog/base.ts +++ b/src/types/spec/dialog/base.ts @@ -1 +1,60 @@ -export interface BaseDialog {} +import { ReactNode, ForwardRefExoticComponent, PropsWithChildren } from 'react' +import type { MouseEvent, CSSProperties } from 'react' +import { WebOverlayProps } from '@/types' +import { BasicComponent } from '@/utils/typings' + +export type DialogConfigType = { + prefixCls?: string + simple?: boolean +} + +export type DialogCloseIconPosition = 'top-right' | 'top-left' | 'bottom' +export type DialogFooterDirection = 'horizontal' | 'vertical' +export interface BaseContentProps extends BasicComponent { + visible: boolean + title: ReactNode + header: ReactNode + footer: ReactNode + close: ReactNode + footerDirection: DialogFooterDirection +} +export interface DialogWrapProps + extends WebOverlayProps, + Omit { + visible: boolean + overlay: boolean + overlayStyle: CSSProperties + overlayClassName: string + onCancel: () => void + onClose: () => void + onOverlayClick: (e: MouseEvent) => boolean | void +} + +export interface BaseDialog extends DialogWrapProps { + content: ReactNode + confirmText: ReactNode + cancelText: ReactNode + hideConfirmButton: boolean + hideCancelButton: boolean + disableConfirmButton: boolean + closeIconPosition: DialogCloseIconPosition + closeIcon: boolean | ReactNode + beforeClose: () => boolean + beforeCancel: () => boolean + onConfirm: (e?: MouseEvent) => PromiseLike | void +} + +export type DialogReturnProps = { + update: (newConfig: Partial) => void + close: () => void +} + +export interface DialogComponent + extends ForwardRefExoticComponent>> { + confirm: (props: Partial) => DialogReturnProps + alert: (props: Partial) => DialogReturnProps + config: (config: DialogConfigType) => void + destroyAll: () => void +} + +export const destroyList: Array<() => void> = [] diff --git a/src/types/spec/dialog/h5.ts b/src/types/spec/dialog/h5.ts index cdf8e570d1..be472031f9 100644 --- a/src/types/spec/dialog/h5.ts +++ b/src/types/spec/dialog/h5.ts @@ -1,3 +1,6 @@ -import { BaseDialog } from './base' +import { BaseDialog, BaseContentProps } from './base' +export interface WebContentProps extends BaseContentProps { + onClick: (event: MouseEvent) => void +} export interface WebDialogProps extends BaseDialog {} diff --git a/src/types/spec/dialog/taro.ts b/src/types/spec/dialog/taro.ts index fdfbdf9793..c5c3ed579d 100644 --- a/src/types/spec/dialog/taro.ts +++ b/src/types/spec/dialog/taro.ts @@ -1,3 +1,12 @@ -import { BaseDialog } from './base' +import { ITouchEvent } from '@tarojs/components' +import { BaseDialog, BaseContentProps } from './base' -export interface TaroDialogProps extends BaseDialog {} +export interface TaroContentProps extends BaseContentProps { + onClick: (event: ITouchEvent) => void +} + +export interface TaroDialogProps + extends Omit { + onClick: (event: ITouchEvent) => void + onOverlayClick: (event: ITouchEvent) => boolean | void +}