Repository: ant-design/ant-design-mobile (ts)

Issue:
SwipeAction 没有 onClose 的方法吗？我需要在左滑或右滑的情况下，点击adm-swipe-action-content，让我知道收起来了，我需要做一些操作
### Version of antd-mobile

谷歌浏览器

### What is this feature about?

_No response_

Pull request:
feat(SwipeAction): support onClose action
close #6585 

Patch:
diff --git a/src/components/swipe-action/index.en.md b/src/components/swipe-action/index.en.md
index ede2be1e0..c02ae5ffd 100644
--- a/src/components/swipe-action/index.en.md
+++ b/src/components/swipe-action/index.en.md
@@ -14,15 +14,16 @@ Swipe to reveal hidden function menus.
 
 ### Props
 
-| Name | Description | Type | Default |
-| --- | --- | --- | --- |
-| closeOnAction | Whether to return to the position automatically when the operation button is clicked | `boolean` | `true` |
-| closeOnTouchOutside | Whether to return to the position automatically when other areas is clicked | `boolean` | `true` |
-| leftActions | List of operation buttons on the left | `Action[]` | `[]` |
-| rightActions | List of operation buttons on the right | `Action[]` | `[]` |
-| onAction | Triggered when operation button is clicked | `(action: Action, e: React.MouseEvent) => void` | - |
-| stopPropagation | Stop the propagation of some events. | `PropagationEvent[]` | `[]` |
-| onActionsReveal | Triggered when the operation button appears completely | `(side: 'left' \| 'right') => void` | - |
+| Name | Description | Type | Default | Version |
+| --- | --- | --- | --- | --- |
+| closeOnAction | Whether to return to the position automatically when the operation button is clicked | `boolean` | `true` |  |
+| closeOnTouchOutside | Whether to return to the position automatically when other areas is clicked | `boolean` | `true` |  |
+| leftActions | List of operation buttons on the left | `Action[]` | `[]` |  |
+| rightActions | List of operation buttons on the right | `Action[]` | `[]` |  |
+| onAction | Triggered when operation button is clicked | `(action: Action, e: React.MouseEvent) => void` | - |  |
+| stopPropagation | Stop the propagation of some events. | `PropagationEvent[]` | `[]` |  |
+| onActionsReveal | Triggered when the operation button appears completely | `(side: 'left' \| 'right') => void` | - |  |
+| onClose | Triggered when the slide bar returns to the position | `() => void` | - | 5.39.0 |
 
 ### Action
 
diff --git a/src/components/swipe-action/index.zh.md b/src/components/swipe-action/index.zh.md
index b9dbcc08b..e5cb5952e 100644
--- a/src/components/swipe-action/index.zh.md
+++ b/src/components/swipe-action/index.zh.md
@@ -14,15 +14,16 @@
 
 ### 属性
 
-| 属性 | 说明 | 类型 | 默认值 |
-| --- | --- | --- | --- |
-| closeOnAction | 是否在点击操作按钮时自动归位 | `boolean` | `true` |
-| closeOnTouchOutside | 是否在点击其他区域时自动归位 | `boolean` | `true` |
-| leftActions | 左侧的操作按钮列表 | `Action[]` | `[]` |
-| rightActions | 右侧的操作按钮列表 | `Action[]` | `[]` |
-| onAction | 点击操作按钮时触发 | `(action: Action, e: React.MouseEvent) => void` | - |
-| stopPropagation | 阻止某些事件的冒泡 | `PropagationEven[]` | `[]` |
-| onActionsReveal | 按钮完全出现时触发 | `(side: 'left' \| 'right') => void` | - |
+| 属性 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| closeOnAction | 是否在点击操作按钮时自动归位 | `boolean` | `true` |  |
+| closeOnTouchOutside | 是否在点击其他区域时自动归位 | `boolean` | `true` |  |
+| leftActions | 左侧的操作按钮列表 | `Action[]` | `[]` |  |
+| rightActions | 右侧的操作按钮列表 | `Action[]` | `[]` |  |
+| onAction | 点击操作按钮时触发 | `(action: Action, e: React.MouseEvent) => void` | - |  |
+| stopPropagation | 阻止某些事件的冒泡 | `PropagationEvent[]` | `[]` |  |
+| onActionsReveal | 按钮完全出现时触发 | `(side: 'left' \| 'right') => void` | - |  |
+| onClose | 滑动条归位时触发 | `() => void` | - | 5.39.0 |
 
 ### Action
 
diff --git a/src/components/swipe-action/swipe-action.tsx b/src/components/swipe-action/swipe-action.tsx
index d519c3db7..9a1e98e75 100644
--- a/src/components/swipe-action/swipe-action.tsx
+++ b/src/components/swipe-action/swipe-action.tsx
@@ -1,3 +1,6 @@
+import { animated, useSpring } from '@react-spring/web'
+import { useDrag } from '@use-gesture/react'
+import type { ReactNode } from 'react'
 import React, {
   forwardRef,
   RefObject,
@@ -5,17 +8,14 @@ import React, {
   useImperativeHandle,
   useRef,
 } from 'react'
-import type { ReactNode } from 'react'
-import { mergeProps } from '../../utils/with-default-props'
-import { useSpring, animated } from '@react-spring/web'
-import { useDrag } from '@use-gesture/react'
-import Button from '../button'
-import { nearest } from '../../utils/nearest'
 import { NativeProps, withNativeProps } from '../../utils/native-props'
+import { nearest } from '../../utils/nearest'
+import { mergeProps } from '../../utils/with-default-props'
 import {
   PropagationEvent,
   withStopPropagation,
 } from '../../utils/with-stop-propagation'
+import Button from '../button'
 
 const classPrefix = `adm-swipe-action`
 
@@ -50,6 +50,7 @@ export type SwipeActionProps = {
   children: ReactNode
   stopPropagation?: PropagationEvent[]
   onActionsReveal?: (side: SideType) => void
+  onClose?: () => void
 } & NativeProps<'--background'>
 
 const defaultProps = {
@@ -150,11 +151,12 @@ export const SwipeAction = forwardRef<SwipeActionRef, SwipeActionProps>(
       }
     )
 
-    function close() {
+    const close = () => {
       api.start({
         x: 0,
       })
       forceCancelDrag()
+      props.onClose?.()
     }
 
     useImperativeHandle(ref, () => ({


Test patch:
diff --git a/src/components/swipe-action/tests/swipe-action.test.tsx b/src/components/swipe-action/tests/swipe-action.test.tsx
index c82f27651..a49057cd6 100644
--- a/src/components/swipe-action/tests/swipe-action.test.tsx
+++ b/src/components/swipe-action/tests/swipe-action.test.tsx
@@ -1,14 +1,14 @@
+import { Dialog } from 'antd-mobile'
 import React, { useRef } from 'react'
 import {
+  fireEvent,
+  mockDrag,
   render,
   testA11y,
-  fireEvent,
-  waitFor,
   userEvent,
-  mockDrag,
+  waitFor,
 } from 'testing'
 import SwipeAction, { Action, SwipeActionProps, SwipeActionRef } from '..'
-import { Dialog } from 'antd-mobile'
 
 const classPrefix = `adm-swipe-action`
 const width = 80
@@ -276,4 +276,18 @@ describe('SwipeAction', () => {
       expect(onActionsReveal).toBeCalledWith('left')
     })
   })
+
+  test('onClose should be called when the swipe action is closed', async () => {
+    const onClose = jest.fn()
+    const { getByTestId, getByText } = render(<App onClose={onClose} />)
+
+    swipe(getByTestId('swipe'), [
+      {
+        clientX: 150,
+      },
+    ])
+
+    await userEvent.click(getByText('pin'))
+    await waitFor(() => expect(onClose).toBeCalledTimes(1))
+  })
 })