fix(workflow): preserve change node menu semantics and focus (#42568)

This commit is contained in:
yyh authored and GitHub committed 2026-09-20 07:04:42 +00:00
1 parent b53e5f23c6
commit dec1658200
8 files changed
+233 -42

No files matched your search

@@ -3,6 +3,8 @@ import { userEvent } from 'vite-plus/test/browser'
import { render } from 'vitest-browser-react'
import {
Popover,
PopoverBackdrop,
PopoverClose,
PopoverContent,
PopoverDescription,
PopoverPopup,
@@ -11,6 +13,12 @@ import {
PopoverTitle,
PopoverTrigger,
} from '..'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '../../dropdown-menu'
const renderWithSafeViewport = (ui: React.ReactNode) =>
render(<div style={{ minHeight: '100vh', minWidth: '100vw', padding: '240px' }}>{ui}</div>)
@@ -95,6 +103,47 @@ describe('PopoverContent', () => {
})
describe('Popover anatomy', () => {
it('places the backdrop above a parent menu and below the interactive popup', async () => {
const backdropRef = React.createRef<HTMLDivElement>()
const screen = await renderWithSafeViewport(
<DropdownMenu modal={false}>
<DropdownMenuTrigger>Actions</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Primary action</DropdownMenuItem>
<Popover modal="trap-focus">
<DropdownMenuItem
closeOnClick={false}
render={<PopoverTrigger nativeButton={false} render={<div />} />}
>
More options
</DropdownMenuItem>
<PopoverPortal>
<PopoverBackdrop ref={backdropRef} />
<PopoverPositioner placement="right-start">
<PopoverPopup>
<PopoverTitle>More options</PopoverTitle>
<input aria-label="Filter options" />
<PopoverClose>Close</PopoverClose>
</PopoverPopup>
</PopoverPositioner>
</PopoverPortal>
</Popover>
</DropdownMenuContent>
</DropdownMenu>,
)
await screen.getByRole('button', { name: 'Actions' }).click()
const primaryAction = screen.getByRole('menuitem', { name: 'Primary action' }).element()
await screen.getByRole('menuitem', { name: 'More options' }).click()
const input = screen.getByRole('textbox', { name: 'Filter options' })
const { x, y, width, height } = primaryAction.getBoundingClientRect()
expect(document.elementFromPoint(x + width / 2, y + height / 2)).toBe(backdropRef.current)
await input.click()
await input.fill('Example')
await expect.element(input).toHaveValue('Example')
})
it('should use the default positioner placement', async () => {
const screen = await renderWithSafeViewport(
<Popover open>
+10
View File
@@ -25,6 +25,14 @@ type PopoverCloseProps = BasePopover.Close.Props
type PopoverTitleProps = BasePopover.Title.Props
type PopoverDescriptionProps = BasePopover.Description.Props
type PopoverBackdropProps = Omit<BasePopover.Backdrop.Props, 'className'> & {
className?: string
}
function PopoverBackdrop({ className, ...props }: PopoverBackdropProps) {
return <BasePopover.Backdrop className={cn('fixed inset-0 z-50', className)} {...props} />
}
type PopoverPositionerProps = Omit<BasePopover.Positioner.Props, 'className' | 'side' | 'align'> & {
className?: string
placement?: Placement
@@ -103,6 +111,7 @@ export {
createPopoverHandle,
Popover,
PopoverArrow,
PopoverBackdrop,
PopoverClose,
PopoverContent,
PopoverDescription,
@@ -114,6 +123,7 @@ export {
}
export type {
PopoverArrowProps,
PopoverBackdropProps,
PopoverCloseProps,
PopoverContentProps,
PopoverDescriptionProps,