Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add closeOnBack to Popup, CenterPopup and other components built on them #6438

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/components/action-sheet/action-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type ActionSheetProps = {
onClose?: () => void
onMaskClick?: () => void
closeOnAction?: boolean
closeOnBack?: boolean
closeOnMaskClick?: boolean
safeArea?: boolean
popupClassName?: string
Expand All @@ -45,6 +46,7 @@ const defaultProps = {
actions: [],
cancelText: '',
closeOnAction: false,
closeOnBack: false,
closeOnMaskClick: true,
safeArea: true,
destroyOnClose: false,
Expand All @@ -64,6 +66,7 @@ export const ActionSheet: FC<ActionSheetProps> = p => {
props.onClose?.()
}
}}
closeOnBack={props.closeOnBack}
afterClose={props.afterClose}
className={classNames(`${classPrefix}-popup`, props.popupClassName)}
style={props.popupStyle}
Expand Down
1 change: 1 addition & 0 deletions src/components/action-sheet/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Triggered by user operation, it provides a set of two or more options related to
| afterClose | Triggered when completely closed | `() => void` | - |
| cancelText | The text of the cancel button , if it is null, the cancel button would not be displayed | `ReactNode` | - |
| closeOnAction | Whether to close after clicking the option | `boolean` | `false` |
| closeOnBack | Whether to close after clicking browser back button or use back swipe guesture | `boolean` | `false` |
| closeOnMaskClick | Whether to close after clicking the mask layer | `boolean` | `true` |
| destroyOnClose | Destroy `dom` when not visible | `boolean` | `false` |
| forceRender | Render content forcely | `boolean` | `false` |
Expand Down
1 change: 1 addition & 0 deletions src/components/action-sheet/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
| afterClose | 完全关闭后触发 | `() => void` | - |
| cancelText | 取消按钮文字,如果设置为空则不显示取消按钮 | `ReactNode` | - |
| closeOnAction | 点击选项后是否关闭 | `boolean` | `false` |
| closeOnBack | 点击后退按钮或滑动后退手势是否关闭 | `boolean` | `false` |
| closeOnMaskClick | 点击背景蒙层后是否关闭 | `boolean` | `true` |
| destroyOnClose | 不可见时是否销毁 `DOM` 结构 | `boolean` | `false` |
| forceRender | 强制渲染内容 | `boolean` | `false` |
Expand Down
1 change: 1 addition & 0 deletions src/components/calendar-picker/calendar-picker.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ When the user needs to enter a date, he can select it in the pop-up date panel.
| popupStyle | The custom style of the popup | `React.CSSProperties` | - |
| popupBodyStyle | The custom style of the popup body | `React.CSSProperties` | - |
| forceRender | Render content forcely,When ref is passed,always be true | `boolean` | `false` |
| closeOnBack | Whether to close after clicking browser back button or use back swipe guesture | `boolean` | `false` |
| closeOnMaskClick | Whether to close after clicking the mask layer | `boolean` | `true` |
| onClose | Triggered when closed | `() => void` | - |
| onMaskClick | Triggered when the mask is clicked | `() => void` | - |
Expand Down
3 changes: 3 additions & 0 deletions src/components/calendar-picker/calendar-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type CalendarPickerProps = CalendarPickerViewProps & {
popupStyle?: React.CSSProperties
popupBodyStyle?: React.CSSProperties
forceRender?: true
closeOnBack?: boolean
closeOnMaskClick?: boolean
onClose?: () => void
onMaskClick?: () => void
Expand Down Expand Up @@ -64,6 +65,7 @@ export const CalendarPicker = forwardRef<
popupStyle,
popupBodyStyle,
forceRender,
closeOnBack,
closeOnMaskClick,
onClose,
onConfirm,
Expand Down Expand Up @@ -117,6 +119,7 @@ export const CalendarPicker = forwardRef<
onClose?.()
}
}}
closeOnBack={closeOnBack}
>
<CalendarPickerView ref={calendarRef} {...calendarViewProps} />
{footer}
Expand Down
1 change: 1 addition & 0 deletions src/components/calendar-picker/calendar-picker.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
| popupStyle | 弹层容器的自定义样式 | `React.CSSProperties` | - |
| popupBodyStyle | 容器内部自定义样式 | `React.CSSProperties` | - |
| forceRender | 强制渲染内容,当传递 ref 时,会强制设为 true | `boolean` | `false` |
| closeOnBack | 点击后退按钮或滑动后退手势是否关闭 | `boolean` | `false` |
| closeOnMaskClick | 点击背景蒙层后是否关闭 | `boolean` | `true` |
| onClose | 关闭时触发 | `() => void` | - |
| onMaskClick | 点击背景蒙层时触发 | `() => void` | - |
Expand Down
17 changes: 16 additions & 1 deletion src/components/center-popup/center-popup.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import type { FC, PropsWithChildren } from 'react'
import { renderToContainer } from '../../utils/render-to-container'
import Mask from '../mask'
Expand Down Expand Up @@ -144,6 +144,21 @@
)
)

useEffect(() => {
if (maskVisible && props.closeOnBack) {
const handlePopState = (e: PopStateEvent) => {

Check warning on line 149 in src/components/center-popup/center-popup.tsx

View workflow job for this annotation

GitHub Actions / check

'e' is defined but never used

Check warning on line 149 in src/components/center-popup/center-popup.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/center-popup/center-popup.tsx#L149

Added line #L149 was not covered by tests
// prevent history back
history.go(1)

Check warning on line 151 in src/components/center-popup/center-popup.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/center-popup/center-popup.tsx#L151

Added line #L151 was not covered by tests
// close popup instead
props.onClose?.()
}
window.addEventListener('popstate', handlePopState)
return () => {
window.removeEventListener('popstate', handlePopState)

Check warning on line 157 in src/components/center-popup/center-popup.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/center-popup/center-popup.tsx#L155-L157

Added lines #L155 - L157 were not covered by tests
}
}
}, [maskVisible])

return (
<ShouldRender
active={active}
Expand Down
2 changes: 2 additions & 0 deletions src/components/date-picker/date-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type DatePickerProps = Pick<
| 'onCancel'
| 'onClose'
| 'closeOnMaskClick'
| 'closeOnBack'
| 'visible'
| 'confirmText'
| 'cancelText'
Expand Down Expand Up @@ -135,6 +136,7 @@ export const DatePicker = forwardRef<DatePickerRef, DatePickerProps>(
value={pickerValue}
onCancel={props.onCancel}
onClose={props.onClose}
closeOnBack={props.closeOnBack}
closeOnMaskClick={props.closeOnMaskClick}
visible={props.visible}
confirmText={props.confirmText}
Expand Down
3 changes: 3 additions & 0 deletions src/components/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ export type DialogProps = Pick<
onAction?: (action: Action, index: number) => void | Promise<void>
onClose?: () => void
closeOnAction?: boolean
closeOnBack?: boolean
closeOnMaskClick?: boolean
} & NativeProps

const defaultProps = {
actions: [] as Action[],
closeOnAction: false,
closeOnBack: false,
closeOnMaskClick: false,
getContainer: null,
}
Expand Down Expand Up @@ -109,6 +111,7 @@ export const Dialog: FC<DialogProps> = p => {
}
: undefined
}
closeOnBack={props.closeOnBack}
visible={props.visible}
getContainer={props.getContainer}
bodyStyle={props.bodyStyle}
Expand Down
1 change: 1 addition & 0 deletions src/components/dialog/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ When users need to process transactions, but do not want to jump to pages to int
| bodyClassName | `Dialog` content class name | `string` | - |
| bodyStyle | `Dialog` content style | `React.CSSProperties` | - |
| closeOnAction | Whether to close after clicking the operation button | `boolean` | `false` |
| closeOnBack | Whether to close after clicking browser back button or use back swipe guesture | `boolean` | `false` |
| closeOnMaskClick | Whether to support clicking the mask to close the dialog box | `boolean` | `false` |
| content | The content of the Dialog | `React.ReactNode` | - |
| destroyOnClose | Destroy `dom` when not visible | `boolean` | `false` |
Expand Down
1 change: 1 addition & 0 deletions src/components/dialog/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
| bodyClassName | `Dialog` 内容类名 | `string` | - |
| bodyStyle | `Dialog` 内容样式 | `React.CSSProperties` | - |
| closeOnAction | 点击操作按钮后后是否关闭 | `boolean` | `false` |
| closeOnBack | 点击后退按钮或滑动后退手势是否关闭 | `boolean` | `false` |
| closeOnMaskClick | 是否支持点击遮罩关闭对话框 | `boolean` | `false` |
| content | 对话框内容 | `React.ReactNode` | - |
| destroyOnClose | 不可见时是否销毁 `DOM` 结构 | `boolean` | `false` |
Expand Down
1 change: 1 addition & 0 deletions src/components/modal/demos/demo1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export default () => {
Modal.show({
content: '点击遮罩关闭',
closeOnMaskClick: true,
closeOnBack: true,
})
}}
>
Expand Down
1 change: 1 addition & 0 deletions src/components/modal/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ When users need to process transactions, but do not want to jump to pages to int
| bodyClassName | `Modal` content class name | `string` | - |
| bodyStyle | `Modal` content style | `React.CSSProperties` | - |
| closeOnAction | Whether to close after clicking the operation button | `boolean` | `false` |
| closeOnBack | Whether to close after clicking browser back button or use back swipe guesture | `boolean` | `false` |
| closeOnMaskClick | Whether to support clicking the mask to close the modal box | `boolean` | `false` |
| content | The content of the Modal | `React.ReactNode` | - |
| destroyOnClose | Destroy `dom` when not visible | `boolean` | `false` |
Expand Down
1 change: 1 addition & 0 deletions src/components/modal/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
| bodyClassName | `Modal` 内容类名 | `string` | - |
| bodyStyle | `Modal` 内容样式 | `React.CSSProperties` | - |
| closeOnAction | 点击操作按钮后后是否关闭 | `boolean` | `false` |
| closeOnBack | 点击后退按钮或滑动后退手势是否关闭 | `boolean` | `false` |
| closeOnMaskClick | 是否支持点击遮罩关闭弹窗 | `boolean` | `false` |
| content | 弹窗内容 | `React.ReactNode` | - |
| destroyOnClose | 不可见时是否销毁 `DOM` 结构 | `boolean` | `false` |
Expand Down
3 changes: 3 additions & 0 deletions src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ export type ModalProps = Pick<
onAction?: (action: Action, index: number) => void | Promise<void>
onClose?: () => void
closeOnAction?: boolean
closeOnBack?: boolean
closeOnMaskClick?: boolean
showCloseButton?: boolean
} & NativeProps

const defaultProps = {
actions: [] as Action[],
closeOnAction: false,
closeOnBack: false,
closeOnMaskClick: false,
getContainer: null,
}
Expand Down Expand Up @@ -99,6 +101,7 @@ export const Modal: FC<ModalProps> = p => {
afterClose={props.afterClose}
afterShow={props.afterShow}
showCloseButton={props.showCloseButton}
closeOnBack={props.closeOnBack}
closeOnMaskClick={props.closeOnMaskClick}
onClose={props.onClose}
visible={props.visible}
Expand Down
1 change: 1 addition & 0 deletions src/components/picker/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type PickerValueExtend = {
| --- | --- | --- | --- |
| cancelText | Text of the cancel button | `ReactNode` | `'取消'` |
| children | Render function of the selected options | `(items: PickerColumnItem[], actions: PickerActions) => ReactNode` | - |
| closeOnBack | Whether to close after clicking browser back button or use back swipe guesture | `boolean` | `false` |
| closeOnMaskClick | Whether to close after clicking the mask layer | `boolean` | `true` |
| columns | Options to configure each column | `PickerColumn[] \| ((value: PickerValue[]) => PickerColumn[])` | - |
| confirmText | Text of the ok button | `ReactNode` | `'确定'` |
Expand Down
1 change: 1 addition & 0 deletions src/components/picker/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type PickerValueExtend = {
| --- | --- | --- | --- |
| cancelText | 取消按钮的文字 | `ReactNode` | `'取消'` |
| children | 所选项的渲染函数 | `(items: PickerColumnItem[], actions: PickerActions) => ReactNode` | - |
| closeOnBack | 点击后退按钮或滑动后退手势是否关闭 | `boolean` | `false` |
| closeOnMaskClick | 点击背景蒙层后是否关闭 | `boolean` | `true` |
| columns | 配置每一列的选项 | `PickerColumn[] \| ((value: PickerValue[]) => PickerColumn[])` | - |
| confirmText | 确定按钮的文字 | `ReactNode` | `'确定'` |
Expand Down
3 changes: 3 additions & 0 deletions src/components/picker/picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export type PickerProps = {
onConfirm?: (value: PickerValue[], extend: PickerValueExtend) => void
onCancel?: () => void
onClose?: () => void
closeOnBack?: boolean
closeOnMaskClick?: boolean
visible?: boolean
title?: ReactNode
Expand Down Expand Up @@ -78,6 +79,7 @@ export type PickerProps = {

const defaultProps = {
defaultValue: [],
closeOnBack: false,
closeOnMaskClick: true,
renderLabel: defaultRenderLabel,
destroyOnClose: false,
Expand Down Expand Up @@ -205,6 +207,7 @@ export const Picker = memo(
props.onCancel?.()
setVisible(false)
}}
closeOnBack={props.closeOnBack}
getContainer={props.getContainer}
destroyOnClose={props.destroyOnClose}
afterShow={props.afterShow}
Expand Down
1 change: 1 addition & 0 deletions src/components/popup/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ It is suitable for displaying pop-up windows, information prompts, selection inp
| bodyClassName | Content section class name | `string` | - |
| bodyStyle | Content section style | `React.CSSProperties` | - |
| className | Container class name | `string` | - |
| closeOnBack | Whether to close after clicking browser back button or use back swipe guesture | `boolean` | `false` |
| closeOnMaskClick | Whether to close after clicking the mask layer | `boolean` | `false` |
| destroyOnClose | Destroy `dom` when not visible | `boolean` | `false` |
| forceRender | Render content forcely | `boolean` | `false` |
Expand Down
1 change: 1 addition & 0 deletions src/components/popup/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
| bodyClassName | 内容区域类名 | `string` | - |
| bodyStyle | 内容区域样式 | `React.CSSProperties` | - |
| className | 容器类名 | `string` | - |
| closeOnBack | 点击后退按钮或滑动后退手势是否关闭 | `boolean` | `false` |
| closeOnMaskClick | 点击背景蒙层后是否关闭 | `boolean` | `false` |
| destroyOnClose | 不可见时是否销毁 `DOM` 结构 | `boolean` | `false` |
| forceRender | 强制渲染内容 | `boolean` | `false` |
Expand Down
2 changes: 2 additions & 0 deletions src/components/popup/popup-base-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type PopupBaseProps = {
afterShow?: () => void
bodyClassName?: string
bodyStyle?: CSSProperties
closeOnBack?: boolean
closeOnMaskClick?: boolean
destroyOnClose?: boolean
disableBodyScroll?: boolean
Expand All @@ -26,6 +27,7 @@ export type PopupBaseProps = {
}

export const defaultPopupBaseProps = {
closeOnBack: false,
closeOnMaskClick: false,
destroyOnClose: false,
disableBodyScroll: true,
Expand Down
17 changes: 16 additions & 1 deletion src/components/popup/popup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames'
import React, { useState, useRef } from 'react'
import React, { useState, useRef, useEffect } from 'react'
import type { FC, PropsWithChildren } from 'react'
import { useIsomorphicLayoutEffect, useUnmountedRef } from 'ahooks'
import { NativeProps, withNativeProps } from '../../utils/native-props'
Expand Down Expand Up @@ -165,6 +165,21 @@
)
)

useEffect(() => {
if (maskVisible && props.closeOnBack) {
const handlePopState = () => {

Check warning on line 170 in src/components/popup/popup.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/popup/popup.tsx#L170

Added line #L170 was not covered by tests
// prevent history back
history.go(1)

Check warning on line 172 in src/components/popup/popup.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/popup/popup.tsx#L172

Added line #L172 was not covered by tests
// close popup instead
props.onClose?.()
}
window.addEventListener('popstate', handlePopState)
return () => {
window.removeEventListener('popstate', handlePopState)

Check warning on line 178 in src/components/popup/popup.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/popup/popup.tsx#L176-L178

Added lines #L176 - L178 were not covered by tests
}
}
}, [maskVisible])

return (
<ShouldRender
active={active}
Expand Down
Loading