mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-17 05:02:23 +08:00
Remove enzyme from links
This commit is contained in:
parent
ffcd6fe938
commit
390b8332ab
@ -45,8 +45,7 @@
|
||||
"ts-dedent": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/webpack-env": "^1.15.2",
|
||||
"enzyme": "^3.11.0"
|
||||
"@types/webpack-env": "^1.15.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -32,11 +32,13 @@ jest.mock('global', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const mockAddons = (addons as unknown) as jest.Mocked<typeof addons>;
|
||||
|
||||
describe('preview', () => {
|
||||
describe('linkTo()', () => {
|
||||
it('should select the kind and story provided', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
const channel = { emit: jest.fn() } as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const handler = linkTo('kind', 'name');
|
||||
handler();
|
||||
@ -48,9 +50,9 @@ describe('preview', () => {
|
||||
});
|
||||
|
||||
it('should select the kind (only) provided', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) => null);
|
||||
const channel = { emit: jest.fn() } as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((): any => null);
|
||||
|
||||
const handler = linkTo('kind');
|
||||
handler();
|
||||
@ -62,10 +64,10 @@ describe('preview', () => {
|
||||
});
|
||||
|
||||
it('should select the story (only) provided', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
const channel = { emit: jest.fn() } as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
// simulate a currently selected, but not found as ID
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) =>
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input: any) =>
|
||||
!input
|
||||
? {
|
||||
kind: 'kind',
|
||||
@ -84,9 +86,9 @@ describe('preview', () => {
|
||||
});
|
||||
|
||||
it('should select the id provided', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) =>
|
||||
const channel = { emit: jest.fn() } as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input: any) =>
|
||||
input === 'kind--story'
|
||||
? {
|
||||
story: 'name',
|
||||
@ -105,11 +107,12 @@ describe('preview', () => {
|
||||
});
|
||||
|
||||
it('should handle functions returning strings', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) => null);
|
||||
const channel = { emit: jest.fn() } as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input: any): any => null);
|
||||
|
||||
const handler = linkTo(
|
||||
// @ts-expect-error
|
||||
(a, b) => a + b,
|
||||
(a, b) => b + a
|
||||
);
|
@ -1,50 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
// NOTE: this is a copy of `lib/components/src/navigation/RoutedLink.js`.
|
||||
// It's duplicated here because that copy has an explicit dependency on
|
||||
// React 16.3+, which breaks older versions of React running in the preview.
|
||||
// The proper DRY solution is to create a new package that doesn't depend
|
||||
// on a specific react version. However, that's a heavy-handed solution for
|
||||
// one trivial file.
|
||||
|
||||
const LEFT_BUTTON = 0;
|
||||
// Cmd/Ctrl/Shift/Alt + Click should trigger default browser behaviour. Same applies to non-left clicks
|
||||
const isPlainLeftClick = (e) =>
|
||||
e.button === LEFT_BUTTON && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey;
|
||||
|
||||
export default class RoutedLink extends React.Component {
|
||||
onClick = (e) => {
|
||||
const { onClick } = this.props;
|
||||
|
||||
if (isPlainLeftClick(e)) {
|
||||
e.preventDefault();
|
||||
onClick(e);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { href, children, onClick, className, style } = this.props;
|
||||
const props = onClick
|
||||
? { href, className, style, onClick: this.onClick }
|
||||
: { href, className, style };
|
||||
return <a {...props}>{children}</a>;
|
||||
}
|
||||
}
|
||||
|
||||
RoutedLink.defaultProps = {
|
||||
onClick: null,
|
||||
href: '#',
|
||||
children: null,
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
};
|
||||
|
||||
RoutedLink.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
href: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
// eslint-disable-next-line react/forbid-prop-types
|
||||
style: PropTypes.object,
|
||||
};
|
32
addons/links/src/react/components/RoutedLink.tsx
Normal file
32
addons/links/src/react/components/RoutedLink.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
|
||||
// NOTE: this is a copy of `lib/components/src/navigation/RoutedLink.js`.
|
||||
// It's duplicated here because that copy has an explicit dependency on
|
||||
// React 16.3+, which breaks older versions of React running in the preview.
|
||||
// The proper DRY solution is to create a new package that doesn't depend
|
||||
// on a specific react version. However, that's a heavy-handed solution for
|
||||
// one trivial file.
|
||||
|
||||
const LEFT_BUTTON = 0;
|
||||
// Cmd/Ctrl/Shift/Alt + Click should trigger default browser behaviour. Same applies to non-left clicks
|
||||
const isPlainLeftClick = (e: React.MouseEvent) =>
|
||||
e.button === LEFT_BUTTON && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey;
|
||||
|
||||
const RoutedLink: React.FC<React.DetailedHTMLProps<
|
||||
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
HTMLAnchorElement
|
||||
>> = ({ href = '#', children, onClick, className, style }) => {
|
||||
const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
if (isPlainLeftClick(e)) {
|
||||
e.preventDefault();
|
||||
onClick(e);
|
||||
}
|
||||
};
|
||||
|
||||
const props = onClick
|
||||
? { href, className, style, onClick: handleClick }
|
||||
: { href, className, style };
|
||||
return <a {...props}>{children}</a>;
|
||||
};
|
||||
|
||||
export default RoutedLink;
|
@ -1,8 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LinkTo render should render a link 1`] = `
|
||||
<a
|
||||
href="originpathname?search=&id=foo--bar"
|
||||
onClick={[Function]}
|
||||
/>
|
||||
`;
|
@ -1,7 +1,7 @@
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import addons from '@storybook/addons';
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { SELECT_STORY } from '@storybook/core-events';
|
||||
import LinkTo from './link';
|
||||
|
||||
@ -28,17 +28,21 @@ const mockChannel = () => {
|
||||
once: jest.fn(),
|
||||
};
|
||||
};
|
||||
const mockAddons = (addons as unknown) as jest.Mocked<typeof addons>;
|
||||
|
||||
describe('LinkTo', () => {
|
||||
describe('render', () => {
|
||||
it('should render a link', async () => {
|
||||
const channel = mockChannel();
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
const channel = mockChannel() as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const wrapper = shallow(<LinkTo kind="foo" story="bar" />);
|
||||
await wrapper.instance().updateHref(wrapper.props());
|
||||
wrapper.update();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const { container } = render(<LinkTo kind="foo" story="bar" />);
|
||||
|
||||
expect(container.firstChild).toMatchInlineSnapshot(`
|
||||
<a
|
||||
href="/"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
@ -47,18 +51,23 @@ describe('LinkTo', () => {
|
||||
const channel = {
|
||||
emit: jest.fn(),
|
||||
on: jest.fn(),
|
||||
};
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
} as any;
|
||||
mockAddons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const wrapper = shallow(<LinkTo kind="foo" story="bar" />);
|
||||
wrapper.simulate('click', { button: 0, preventDefault: () => {} });
|
||||
expect(channel.emit.mock.calls).toContainEqual([
|
||||
render(
|
||||
<LinkTo kind="foo" story="bar">
|
||||
link
|
||||
</LinkTo>
|
||||
);
|
||||
userEvent.click(screen.getByText('link'));
|
||||
|
||||
expect(channel.emit).toHaveBeenLastCalledWith(
|
||||
SELECT_STORY,
|
||||
{
|
||||
expect.objectContaining({
|
||||
kind: 'foo',
|
||||
story: 'bar',
|
||||
},
|
||||
]);
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -2,7 +2,7 @@
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"types": ["webpack-env"]
|
||||
"types": ["webpack-env", "@testing-library/jest-dom"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
|
Loading…
x
Reference in New Issue
Block a user