Skip to content

Commit cd16f7d

Browse files
feat(router): optional router in SIdebarToggle
1 parent 269f585 commit cd16f7d

File tree

3 files changed

+103
-35
lines changed

3 files changed

+103
-35
lines changed

src/elements/content-sidebar/SidebarToggle.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,46 @@ import * as React from 'react';
88
import { withRouter, type RouterHistory } from 'react-router-dom';
99
import SidebarToggleButton from '../../components/sidebar-toggle-button/SidebarToggleButton';
1010
import { SIDEBAR_NAV_TARGETS } from '../common/interactionTargets';
11+
import type { InternalSidebarNavigation, InternalSidebarNavigationHandler } from '../common/types/SidebarNavigation';
1112

1213
type Props = {
13-
history: RouterHistory,
14+
history?: RouterHistory,
15+
internalSidebarNavigation?: InternalSidebarNavigation,
16+
internalSidebarNavigationHandler?: InternalSidebarNavigationHandler,
1417
isOpen?: boolean,
18+
routerDisabled?: boolean,
1519
};
1620

17-
const SidebarToggle = ({ history, isOpen }: Props) => {
21+
const SidebarToggle = ({
22+
history,
23+
internalSidebarNavigation,
24+
internalSidebarNavigationHandler,
25+
isOpen,
26+
routerDisabled = false,
27+
}: Props) => {
28+
const handleToggleClick = event => {
29+
event.preventDefault();
30+
31+
if (routerDisabled) {
32+
// Use internal navigation handler when router is disabled
33+
if (internalSidebarNavigationHandler && internalSidebarNavigation) {
34+
internalSidebarNavigationHandler({
35+
...internalSidebarNavigation,
36+
open: !isOpen,
37+
}, true); // Always use replace for toggle
38+
}
39+
} else if (history) {
40+
history.replace({ state: { open: !isOpen } });
41+
}
42+
};
43+
1844
return (
1945
<SidebarToggleButton
2046
data-resin-target={SIDEBAR_NAV_TARGETS.TOGGLE}
2147
data-testid="sidebartoggle"
2248
// $FlowFixMe
2349
isOpen={isOpen}
24-
onClick={event => {
25-
event.preventDefault();
26-
history.replace({ state: { open: !isOpen } });
27-
}}
50+
onClick={handleToggleClick}
2851
/>
2952
);
3053
};
Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,87 @@
11
import * as React from 'react';
2-
import { shallow } from 'enzyme/build';
2+
import { render, screen, userEvent } from '../../../test-utils/testing-library';
33
import { SidebarToggleComponent as SidebarToggle } from '../SidebarToggle';
44

55
describe('elements/content-sidebar/SidebarToggle', () => {
66
const historyMock = { replace: jest.fn() };
7-
const getWrapper = (props = {}) => shallow(<SidebarToggle history={historyMock} {...props} />);
7+
8+
beforeEach(() => {
9+
jest.clearAllMocks();
10+
});
11+
12+
const renderSidebarToggle = (props = {}) => {
13+
return render(<SidebarToggle history={historyMock} {...props} />);
14+
};
815

916
test.each`
10-
isOpen | location
17+
isOpen | expectedState
1118
${true} | ${{ state: { open: false } }}
1219
${false} | ${{ state: { open: true } }}
13-
`('should render and handle clicks correctly when isOpen is $isOpen', ({ isOpen, location }) => {
14-
const event = { preventDefault: jest.fn() };
15-
const wrapper = getWrapper({ isOpen });
20+
`('should render and handle clicks correctly when isOpen is $isOpen', async ({ isOpen, expectedState }) => {
21+
const user = userEvent();
22+
renderSidebarToggle({ isOpen });
23+
24+
const toggleButton = screen.getByTestId('sidebartoggle');
25+
expect(toggleButton).toBeInTheDocument();
26+
27+
await user.click(toggleButton);
28+
29+
expect(historyMock.replace).toHaveBeenCalledWith(expectedState);
30+
});
31+
});
1632

17-
wrapper.simulate('click', event);
33+
describe('elements/content-sidebar/SidebarToggle - Router Disabled', () => {
34+
const mockInternalSidebarNavigationHandler = jest.fn();
35+
const defaultProps = {
36+
routerDisabled: true,
37+
internalSidebarNavigation: { sidebar: 'activity' },
38+
internalSidebarNavigationHandler: mockInternalSidebarNavigationHandler,
39+
};
1840

19-
expect(event.preventDefault).toHaveBeenCalled();
20-
expect(historyMock.replace).toHaveBeenCalledWith(location);
21-
expect(wrapper).toMatchSnapshot();
41+
beforeEach(() => {
42+
jest.clearAllMocks();
2243
});
44+
45+
const renderSidebarToggle = (props = {}) => {
46+
return render(<SidebarToggle {...defaultProps} {...props} />);
47+
};
48+
49+
test.each`
50+
isOpen | expectedNavigation
51+
${true} | ${{ sidebar: 'activity', open: false }}
52+
${false} | ${{ sidebar: 'activity', open: true }}
53+
`('should handle toggle clicks correctly when isOpen is $isOpen', async ({ isOpen, expectedNavigation }) => {
54+
const user = userEvent();
55+
renderSidebarToggle({ isOpen });
56+
57+
const toggleButton = screen.getByTestId('sidebartoggle');
58+
expect(toggleButton).toBeInTheDocument();
59+
await user.click(toggleButton);
60+
61+
expect(mockInternalSidebarNavigationHandler).toHaveBeenCalledWith(expectedNavigation, true);
62+
});
63+
64+
test('should handle complex navigation state correctly', async () => {
65+
const user = userEvent();
66+
const complexNavigation = {
67+
sidebar: 'activity',
68+
versionId: '123',
69+
activeFeedEntryType: 'comments',
70+
activeFeedEntryId: '456',
71+
};
72+
73+
renderSidebarToggle({
74+
isOpen: true,
75+
internalSidebarNavigation: complexNavigation,
76+
});
77+
78+
const toggleButton = screen.getByTestId('sidebartoggle');
79+
await user.click(toggleButton);
80+
81+
expect(mockInternalSidebarNavigationHandler).toHaveBeenCalledWith({
82+
...complexNavigation,
83+
open: false,
84+
}, true);
85+
});
86+
2387
});

src/elements/content-sidebar/__tests__/__snapshots__/SidebarToggle.test.js.snap

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)