Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ describe('<Dialog.Root />', () => {

return (
<div>
<Dialog.Root open={open} triggerId={triggerId}>
<Dialog.Root open={open} triggerId={triggerId} onOpenChange={setOpen}>
{({ payload }: NumberPayload) => (
<React.Fragment>
<Dialog.Trigger id="trigger-1" payload={1}>
Expand All @@ -196,6 +196,7 @@ describe('<Dialog.Root />', () => {
<Dialog.Portal>
<Dialog.Popup>
<span data-testid="content">{payload}</span>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</React.Fragment>
Expand Down Expand Up @@ -223,6 +224,13 @@ describe('<Dialog.Root />', () => {
await waitFor(() => {
expect(screen.getByTestId('content').textContent).toBe('2');
});

await user.click(screen.getByRole('button', { name: 'Close' }));

await waitFor(() => {
expect(screen.queryByTestId('content')).toBe(null);
});
expect(openButton).toHaveFocus();
});

it('keeps the payload reactive', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,9 +730,10 @@ export function FloatingFocusManager(props: FloatingFocusManagerProps): React.JS
}

const doc = ownerDocument(floatingFocusElement);
const previouslyFocusedElement = activeElement(doc);
const elementFocusedBeforeOpen = activeElement(doc);
const preferPreviousFocus = openInteractionTypeRef.current == null;

addPreviouslyFocusedElement(previouslyFocusedElement);
addPreviouslyFocusedElement(elementFocusedBeforeOpen);

// Dismissing via outside press should always ignore `returnFocus` to
// prevent unwanted scrolling.
Expand Down Expand Up @@ -793,17 +794,21 @@ export function FloatingFocusManager(props: FloatingFocusManagerProps): React.JS
resolvedReturnFocusValue = true;
}

if (typeof resolvedReturnFocusValue === 'boolean') {
if (domReference?.isConnected) {
return domReference;
}

return getPreviouslyFocusedElement() || null;
const referenceReturnElement = domReference?.isConnected ? domReference : null;
let previousReturnElement = elementFocusedBeforeOpen;
if (!previousReturnElement?.isConnected || getNodeName(previousReturnElement) === 'body') {
previousReturnElement = getPreviouslyFocusedElement() || null;
}

const fallback = domReference?.isConnected ? domReference : getPreviouslyFocusedElement();
const defaultReturnElement = preferPreviousFocus
? previousReturnElement || referenceReturnElement
: referenceReturnElement || previousReturnElement;

return resolveRef(resolvedReturnFocusValue) || fallback || null;
if (typeof resolvedReturnFocusValue === 'boolean') {
return defaultReturnElement;
}

return resolveRef(resolvedReturnFocusValue) || defaultReturnElement || null;
}

return () => {
Expand Down Expand Up @@ -850,6 +855,7 @@ export function FloatingFocusManager(props: FloatingFocusManagerProps): React.JS
floating,
floatingFocusElement,
returnFocusRef,
openInteractionTypeRef,
events,
tree,
domReference,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ describe('<Popover.Root />', () => {
<Popover.Positioner>
<Popover.Popup>
<span data-testid="content">{payload as number}</span>
<Popover.Close>Close</Popover.Close>
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
Expand All @@ -212,18 +213,20 @@ describe('<Popover.Root />', () => {
>
Open Trigger 2
</button>
<button onClick={() => setOpen(false)}>Close</button>
<button onClick={() => setOpen(false)}>Close externally</button>
</div>
);
}

const { user } = await render(<Test />);
await user.click(screen.getByRole('button', { name: 'Open Trigger 1' }));
expect(screen.getByTestId('content').textContent).toBe('1');
await user.click(screen.getByRole('button', { name: 'Open Trigger 2' }));
const openTrigger2Button = screen.getByRole('button', { name: 'Open Trigger 2' });
await user.click(openTrigger2Button);
expect(screen.getByTestId('content').textContent).toBe('2');
await user.click(screen.getByRole('button', { name: 'Close' }));
expect(screen.queryByTestId('content')).toBe(null);
expect(openTrigger2Button).toHaveFocus();
});

it('allows setting an initially open popover', async () => {
Expand Down
Loading