fix(dify-ui): honor instant popup transitions (#39572)

This commit is contained in:
yyh 2026-07-26 15:08:27 +08:00 committed by GitHub
parent 8511a3143e
commit 448e378fc0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 1 deletions

View File

@ -11,7 +11,7 @@ export const floatingSeparatorClassName = 'my-1 h-px bg-divider-subtle'
export const menuPopupClassName =
'max-h-(--available-height) overflow-y-auto overflow-x-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur py-1 text-sm text-text-secondary shadow-lg outline-hidden focus:outline-hidden focus-visible:outline-hidden backdrop-blur-[5px]'
export const floatingPopupAnimationClassName =
'origin-(--transform-origin) transition-[transform,scale,opacity] data-ending-style:scale-95 data-starting-style:scale-95 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none'
'origin-(--transform-origin) transition-[transform,scale,opacity] data-ending-style:scale-95 data-starting-style:scale-95 data-ending-style:opacity-0 data-starting-style:opacity-0 data-instant:transition-none motion-reduce:transition-none'
export const modalBackdropClassName =
'absolute inset-0 z-50 bg-background-overlay transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none'
export const modalPopupAnimationClassName =

View File

@ -1,4 +1,5 @@
import type * as React from 'react'
import { userEvent } from 'vite-plus/test/browser'
import { render } from 'vitest-browser-react'
import { Popover, PopoverContent, PopoverTrigger } from '..'
@ -6,6 +7,43 @@ const renderWithSafeViewport = (ui: React.ReactNode) =>
render(<div style={{ minHeight: '100vh', minWidth: '100vw', padding: '240px' }}>{ui}</div>)
describe('PopoverContent', () => {
describe('Animation', () => {
it('should restore focus without waiting for an instant close transition', async () => {
const animationSettings = globalThis as typeof globalThis & {
BASE_UI_ANIMATIONS_DISABLED: boolean
}
const animationsDisabled = animationSettings.BASE_UI_ANIMATIONS_DISABLED
animationSettings.BASE_UI_ANIMATIONS_DISABLED = false
try {
const screen = await renderWithSafeViewport(
<Popover>
<PopoverTrigger>Open</PopoverTrigger>
<PopoverContent
popupClassName="duration-[30s]"
popupProps={{ role: 'dialog', 'aria-label': 'popover content' }}
>
<button type="button">Focusable content</button>
</PopoverContent>
</Popover>,
)
const trigger = screen.getByRole('button', { name: 'Open' })
await trigger.click()
const focusableContent = screen.getByRole('button', { name: 'Focusable content' })
focusableContent.element().focus()
await expect.element(focusableContent).toHaveFocus()
await userEvent.keyboard('{Escape}')
await expect.element(trigger).toHaveFocus()
} finally {
animationSettings.BASE_UI_ANIMATIONS_DISABLED = animationsDisabled
}
})
})
describe('Placement', () => {
it('should use bottom placement and default offsets when placement props are not provided', async () => {
const screen = await renderWithSafeViewport(