Skip to content

Commit

Permalink
[Dialog] Don't call onNestedDialogOpen when unmounting a closed nes…
Browse files Browse the repository at this point in the history
…ted dialog (#1280)
  • Loading branch information
mj12albert authored Jan 6, 2025
1 parent 3d2f42f commit a2da3d1
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 5 deletions.
162 changes: 161 additions & 1 deletion packages/react/src/dialog/popup/DialogPopup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import * as React from 'react';
import { expect } from 'chai';
import { Dialog } from '@base-ui-components/react/dialog';
import { AlertDialog } from '@base-ui-components/react/alert-dialog';
import { act, waitFor, screen } from '@mui/internal-test-utils';
import { act, describeSkipIf, waitFor, screen } from '@mui/internal-test-utils';
import { describeConformance, createRenderer } from '#test-utils';

const isJSDOM = /jsdom/.test(window.navigator.userAgent);

describe('<Dialog.Popup />', () => {
const { render } = createRenderer();

Expand Down Expand Up @@ -203,6 +205,164 @@ describe('<Dialog.Popup />', () => {
});
});

describeSkipIf(isJSDOM)('nested dialog count', () => {
it('provides the number of open nested dialogs as a CSS variable', async () => {
const { user } = await render(
<Dialog.Root>
<Dialog.Trigger>Trigger 0</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup0">
<Dialog.Root>
<Dialog.Trigger>Trigger 1</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup1">
<Dialog.Root>
<Dialog.Trigger>Trigger 2</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup2">
<Dialog.Close>Close 2</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
<Dialog.Close>Close 1</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>,
);

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

await waitFor(() => {
expect(screen.getByTestId('popup0')).not.to.equal(null);
});

const computedStyles = getComputedStyle(screen.getByTestId('popup0'));

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('0');

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

await waitFor(() => {
expect(screen.getByTestId('popup1')).not.to.equal(null);
});

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('1');

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

await waitFor(() => {
expect(screen.getByTestId('popup2')).not.to.equal(null);
});

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('2');

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

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('1');

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

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('0');
});

it('decrements the count when an open nested dialog is unmounted', async () => {
function App() {
const [showNested, setShowNested] = React.useState(true);
return (
<React.Fragment>
<button onClick={() => setShowNested(!showNested)}>toggle</button>
<Dialog.Root>
<Dialog.Trigger>Trigger 0</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup0">
{showNested && (
<Dialog.Root>
<Dialog.Trigger>Trigger 1</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup1">
<Dialog.Close>Close 1</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
)}
<Dialog.Close>Close 0</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
</React.Fragment>
);
}

const { user } = await render(<App />);

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

await waitFor(() => {
expect(screen.getByTestId('popup0')).not.to.equal(null);
});

const computedStyles = getComputedStyle(screen.getByTestId('popup0'));

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('0');

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

await waitFor(() => {
expect(screen.getByTestId('popup1')).not.to.equal(null);
});

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('1');

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

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('0');
});

it('does not change the count when a closed nested dialog is unmounted', async () => {
function App() {
const [showNested, setShowNested] = React.useState(true);
return (
<Dialog.Root>
<Dialog.Trigger>Trigger 0</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup0">
{showNested && (
<Dialog.Root>
<Dialog.Trigger />
<Dialog.Portal>
<Dialog.Popup />
</Dialog.Portal>
</Dialog.Root>
)}
<button onClick={() => setShowNested(!showNested)}>toggle</button>
<Dialog.Close>Close 0</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
);
}

const { user } = await render(<App />);

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

await waitFor(() => {
expect(screen.getByTestId('popup0')).not.to.equal(null);
});

const computedStyles = getComputedStyle(screen.getByTestId('popup0'));

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('0');

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

expect(computedStyles.getPropertyValue('--nested-dialogs')).to.equal('0');
});
});

describe('style hooks', () => {
it('adds the `nested` and `has-nested-dialogs` style hooks if a dialog has a parent dialog', async () => {
await render(
Expand Down
4 changes: 0 additions & 4 deletions packages/react/src/dialog/root/useDialogRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ export function useDialogRoot(parameters: useDialogRoot.Parameters): useDialogRo
if (onNestedDialogClose && open) {
onNestedDialogClose();
}

if (onNestedDialogOpen && !open) {
onNestedDialogOpen(ownNestedOpenDialogs);
}
};
}, [open, onNestedDialogClose, onNestedDialogOpen, ownNestedOpenDialogs]);

Expand Down

0 comments on commit a2da3d1

Please sign in to comment.