Skip to content

Commit

Permalink
fix(Toast): multiple toasts should show last one (#6729)
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoyao96 authored Aug 28, 2024
1 parent f7c4c1c commit 7e6f7e6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
11 changes: 8 additions & 3 deletions src/components/toast/methods.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react'
import { InternalToast, ToastProps } from './toast'
import { mergeProps } from '../../utils/with-default-props'
import {
ImperativeHandler,
renderImperatively,
} from '../../utils/render-imperatively'
import { mergeProps } from '../../utils/with-default-props'
import { InternalToast, ToastProps } from './toast'

let currentHandler: ImperativeHandler | null = null
let currentTimeout: number | null = null
Expand Down Expand Up @@ -42,7 +42,12 @@ export function show(p: ToastShowProps | string) {
/>
)
if (currentHandler) {
currentHandler.replace(element)
if (currentHandler.isRendered?.()) {
currentHandler.replace(element)
} else {
currentHandler.close()
currentHandler = renderImperatively(element)
}
} else {
currentHandler = renderImperatively(element)
}
Expand Down
28 changes: 25 additions & 3 deletions src/components/toast/tests/toast.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useRef } from 'react'
import {
render,
act,
fireEvent,
render,
screen,
waitFor,
waitForElementToBeRemoved,
act,
screen,
} from 'testing'
import Toast, { ToastHandler } from '..'

Expand Down Expand Up @@ -255,4 +255,26 @@ describe('Toast', () => {
await waitForContentShow('content2')
expect(document.querySelectorAll(`.${classPrefix}-main`).length)
})

test('multiple toasts should show last one', async () => {
const { getByText } = render(
<button
onClick={() => {
Toast.show({
content: 'content',
duration: 0,
})
Toast.show({
content: 'content2',
duration: 0,
})
}}
>
btn
</button>
)
fireEvent.click(getByText('btn'))
await waitForContentShow('content2')
expect(document.querySelectorAll(`.${classPrefix}-main`).length)
})
})
6 changes: 5 additions & 1 deletion src/utils/render-imperatively.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'
import type { ReactElement } from 'react'
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'
import { renderToBody } from './render-to-body'

type ImperativeProps = {
Expand All @@ -13,6 +13,7 @@ type TargetElement = ReactElement<ImperativeProps>
export type ImperativeHandler = {
close: () => void
replace: (element: TargetElement) => void
isRendered?: () => boolean
}

export function renderImperatively(element: TargetElement) {
Expand Down Expand Up @@ -60,12 +61,15 @@ export function renderImperatively(element: TargetElement) {
if (!wrapperRef.current) {
// it means the wrapper is not mounted yet, call `unmount` directly
unmount()
// call `afterClose` to make sure the callback is called
element.props.afterClose?.()
} else {
wrapperRef.current?.close()
}
},
replace: element => {
wrapperRef.current?.replace(element)
},
isRendered: () => !!wrapperRef.current,
} as ImperativeHandler
}

0 comments on commit 7e6f7e6

Please sign in to comment.