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
6 changes: 6 additions & 0 deletions .changeset/close-menu-on-story-select.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@storybook/react-native-ui': patch
'@storybook/react-native-ui-lite': patch
---

The mobile story list now closes once you pick a story from it, as it does in Storybook for the web, so the selected story is visible straight away. Expanding or collapsing a group still leaves the list open.
4 changes: 4 additions & 0 deletions packages/react-native-ui-lite/src/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ export const Layout = ({
const channel = addons.getChannel();

channel.emit(SET_CURRENT_STORY, { storyId: newStoryId });

// As on Storybook for the web, the mobile story list closes once a story is chosen from it.
// The drawer isn't rendered on desktop, where the ref stays empty.
mobileMenuDrawerRef.current?.setMobileMenuOpen(false);
}, []);

return (
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-ui/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const config = {
resolver: 'react-native-reanimated/jest/resolver',
...(process.env.JEST_CACHE_DIRECTORY && { cacheDirectory: process.env.JEST_CACHE_DIRECTORY }),
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?|@gorhom|@storybook))',
'node_modules/(?!((jest-)?react-native|@react-native(-community)?|@gorhom|@storybook|storybook))',
],
};
module.exports = config;
69 changes: 69 additions & 0 deletions packages/react-native-ui/src/Layout.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { theme, ThemeProvider } from '@storybook/react-native-theming';
import { LayoutProvider, StorageProvider } from '@storybook/react-native-ui-common';
import { fireEvent, render, screen } from '@testing-library/react-native';
import { Text } from 'react-native';
import { SET_CURRENT_STORY } from 'storybook/internal/core-events';
import type { API_IndexHash } from 'storybook/internal/types';
import { Layout } from './Layout';
import { mockDataset } from './mockdata';

const mockEmit = jest.fn();

jest.mock('storybook/manager-api', () => ({
addons: {
getChannel: () => ({ emit: mockEmit }),
getElements: () => ({}),
},
}));

const mockSetMobileMenuOpen = jest.fn();

// Record what the layout asks of the drawer. Like the real one, which keeps its content mounted
// while closed, this renders the story list straight away.
jest.mock('./MobileMenuDrawer', () => {
const React = require('react');

return {
MobileMenuDrawer: React.forwardRef(function MobileMenuDrawer({ children }, ref) {
React.useImperativeHandle(ref, () => ({ setMobileMenuOpen: mockSetMobileMenuOpen }));

return children;
}),
};
});

const storage = {
getItem: async () => null,
setItem: async () => {},
};

const renderUI = async () => {
await render(
<ThemeProvider theme={theme}>
<StorageProvider storage={storage}>
<LayoutProvider>
<Layout storyHash={mockDataset.withRoot as API_IndexHash}>
<Text>Story content</Text>
</Layout>
</LayoutProvider>
</StorageProvider>
</ThemeProvider>
);
};

describe('Layout', () => {
it('closes the mobile story list once a story is selected, but not when a group is toggled', async () => {
await renderUI();

await fireEvent.press(screen.getByText('Group 1'), { preventDefault: jest.fn() });

expect(mockEmit).not.toHaveBeenCalled();
expect(mockSetMobileMenuOpen).not.toHaveBeenCalled();

await fireEvent.press(screen.getByText('Child B1'));

expect(mockEmit).toHaveBeenCalledWith(SET_CURRENT_STORY, { storyId: 'group-1--child-b1' });
expect(mockSetMobileMenuOpen).toHaveBeenCalledTimes(1);
expect(mockSetMobileMenuOpen).toHaveBeenCalledWith(false);
});
});
4 changes: 4 additions & 0 deletions packages/react-native-ui/src/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ export const Layout = ({
const channel = addons.getChannel();

channel.emit(SET_CURRENT_STORY, { storyId: newStoryId });

// As on Storybook for the web, the mobile story list closes once a story is chosen from it.
// The drawer isn't rendered on desktop, where the ref stays empty.
mobileMenuDrawerRef.current?.setMobileMenuOpen(false);
}, []);

return (
Expand Down
Loading