Skip to content

Commit

Permalink
feat: dialog 支持函数调用 (#1315)
Browse files Browse the repository at this point in the history
* feat: dialog add function call

* feat: dialog 支持函数调用
  • Loading branch information
oasis-cloud authored Aug 16, 2023
1 parent ffc86a4 commit ef6139f
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 86 deletions.
1 change: 1 addition & 0 deletions src/packages/dialog/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface BasicDialogProps {
onConfirm?: (e?: MouseEvent<HTMLButtonElement>) => Promise<() => void> | void
onCancel?: () => void
onClick?: () => void
onOverlayClick?: () => void
}

export type DialogReturnProps = {
Expand Down
3 changes: 2 additions & 1 deletion src/packages/dialog/content.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ interface ContentProps {
}

export const Content: FunctionComponent<
Partial<ContentProps> & Omit<HTMLAttributes<HTMLDivElement>, 'onClick'>
Partial<ContentProps> &
Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'title'>
> = (props) => {
const { visible, title, footer, footerDirection, onClick, children } = props

Expand Down
16 changes: 16 additions & 0 deletions src/packages/dialog/demo.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ const DialogDemo = () => {
<>
<Header />
<div className={`demo ${Taro.getEnv() === 'WEB' ? 'web' : ''}`}>
<h2>函数调用</h2>
<Dialog id="test" />
<Cell
title="函数调用"
onClick={() =>
Dialog.open('test', {
title: 'ok?',
onConfirm: () => {
Dialog.close('test')
},
onCancel: () => {
Dialog.close('test')
},
})
}
/>
<h2>{translated.title1}</h2>
<Cell title={translated.basic} onClick={() => setVisible1(true)} />
<Dialog
Expand Down
215 changes: 140 additions & 75 deletions src/packages/dialog/dialog.taro.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
import React, { forwardRef } from 'react'
import React, { FunctionComponent } from 'react'
import type { MouseEvent } from 'react'
import classNames from 'classnames'
import { CSSTransition } from 'react-transition-group'
import { View } from '@tarojs/components'
import Button from '@/packages/button/index.taro'
import { BasicDialogProps } from './config'
import { DialogWrap } from './dialogwrap.taro'
import { Content } from './content.taro'
import { useConfig } from '@/packages/configprovider/configprovider.taro'
import Overlay from '@/packages/overlay/index.taro'
import {
customEvents,
useCustomEvent,
useCustomEventsPath,
useParams,
} from '@/utils/use-custom-event'
import { BasicComponent } from '@/utils/typings'

export type DialogProps = BasicDialogProps
export type DialogProps = BasicDialogProps & BasicComponent
const defaultProps = {
title: '',
content: '',
footer: '',
confirmText: '',
cancelText: '',
overlay: true,
Expand All @@ -20,103 +32,156 @@ const defaultProps = {
lockScroll: true,
beforeCancel: () => true,
beforeClose: () => true,
onOverlayClick: () => undefined,
} as DialogProps

export const BaseDialog = forwardRef(
(
props: Partial<DialogProps> &
Omit<
React.HTMLAttributes<HTMLDivElement>,
'title' | 'content' | 'onClick'
>,
ref
) => {
const { locale } = useConfig()
const {
export const BaseDialog: FunctionComponent<Partial<DialogProps>> & {
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<HTMLButtonElement>) => {
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<HTMLButtonElement>) => {
e.stopPropagation()
onClose?.()
onConfirm?.(e)
}
const renderFooter = () => {
if (footer === null) return ''

return (
footer || (
<>
{!hideCancelButton && (
<Button
size="small"
fill="outline"
type="primary"
className={`${classPrefix}__footer-cancel`}
onClick={(e) => handleCancel(e)}
>
{cancelText || locale.cancel}
</Button>
)}
{!hideConfirmButton && (
<Button
size="small"
type="primary"
className={classNames(`${classPrefix}__footer-ok`, {
disabled: disableConfirmButton,
})}
disabled={disableConfirmButton}
onClick={(e) => handleOk(e)}
>
{confirmText || locale.confirm}
</Button>
)}
</>
)
)
const handleCancel = (e: MouseEvent<HTMLButtonElement>) => {
e.stopPropagation()
if (!beforeCancel?.()) return
if (!beforeClose?.()) return
onClose?.()
onCancel?.()
}

const handleOk = (e: MouseEvent<HTMLButtonElement>) => {
e.stopPropagation()
onClose?.()
onConfirm?.(e)
}
return (
<View
style={{ display: visible ? 'block' : 'none' }}
catchMove={lockScroll}
>
<DialogWrap
{...props}
visible={visible}
lockScroll={lockScroll}
footer={renderFooter()}
onClose={onClose}
onCancel={onCancel}
/>
</View>
footer || (
<>
{!hideCancelButton && (
<Button
size="small"
fill="outline"
type="primary"
className={`${classPrefix}__footer-cancel`}
onClick={(e) => handleCancel(e)}
>
{cancelText || locale.cancel}
</Button>
)}
{!hideConfirmButton && (
<Button
size="small"
type="primary"
className={classNames(`${classPrefix}__footer-ok`, {
disabled: disableConfirmButton,
})}
disabled={disableConfirmButton}
onClick={(e) => handleOk(e)}
>
{confirmText || locale.confirm}
</Button>
)}
</>
)
)
}
)
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 (
<View
style={{ display: visible ? 'block' : 'none' }}
catchMove={lockScroll}
>
<>
{overlay ? (
<Overlay
visible
closeOnOverlayClick={closeOnOverlayClick}
lockScroll={lockScroll}
onClick={onHandleClickOverlay}
/>
) : null}

<CSSTransition
in={visible}
timeout={300}
classNames="fadeDialog"
unmountOnExit
appear
>
<Content
title={title}
footer={renderFooter()}
footerDirection={footerDirection}
visible={visible}
/>
</CSSTransition>
</>
</View>
)
}

export function open(selector: string, options: Partial<typeof defaultProps>) {
// 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
43 changes: 43 additions & 0 deletions src/packages/dialog/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 id="test" />
<Cell
title="函数调用"
onClick={() =>
Dialog.open('test', {
title: 'ok?',
onConfirm: () => {
Dialog.close('test')
},
onCancel: () => {
Dialog.close('test')
},
})
}
/>
</>
)
}
export default App;
```

:::


### 组件调用

:::demo
Expand Down Expand Up @@ -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,

## 主题定制

### 样式变量
Expand Down
15 changes: 8 additions & 7 deletions src/packages/toast/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -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


## 主题定制

Expand Down
Loading

0 comments on commit ef6139f

Please sign in to comment.