Skip to content

Commit

Permalink
Merge pull request #6246 from sairus2k/ts-migration/addon-links
Browse files Browse the repository at this point in the history
Migrate addon links to TS
  • Loading branch information
ndelangen authored Mar 25, 2019
2 parents 301d578 + 17fa318 commit 6a1bebc
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 42 deletions.
2 changes: 1 addition & 1 deletion addons/links/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ export const ADDON_ID = 'storybook/links';

export default {
NAVIGATE: `${ADDON_ID}/navigate`,
REQUEST: `${ADDON_ID}/request`,
RECEIVE: `${ADDON_ID}/receive`,
};
2 changes: 1 addition & 1 deletion addons/links/src/index.js → addons/links/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { linkTo, hrefTo, withLinks } from './preview';

let hasWarned = false;

export function LinkTo() {
export function LinkTo(): null {
if (!hasWarned) {
// eslint-disable-next-line no-console
console.error(stripIndents`
Expand Down
File renamed without changes.
26 changes: 17 additions & 9 deletions addons/links/src/preview.js → addons/links/src/preview.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { SyntheticEvent } from 'react';
import { document } from 'global';
import qs from 'qs';
import addons from '@storybook/addons';
import { SELECT_STORY, STORY_CHANGED } from '@storybook/core-events';
import { toId } from '@storybook/router/utils';
import { toId } from '@storybook/router';

export const navigate = params => addons.getChannel().emit(SELECT_STORY, params);
const generateUrl = id => {
interface Params {
kind: string;
story: string;
}

export const navigate = (params: Params) => addons.getChannel().emit(SELECT_STORY, params);

const generateUrl = (id: string) => {
const { location } = document;
const query = qs.parse(location.search, { ignoreQueryPrefix: true });
return `${location.origin + location.pathname}?${qs.stringify(
Expand All @@ -14,23 +21,24 @@ const generateUrl = id => {
)}`;
};

const valueOrCall = args => value => (typeof value === 'function' ? value(...args) : value);
const valueOrCall = (args: string[]) => (value: string | ((...args: string[]) => string)) =>
typeof value === 'function' ? value(...args) : value;

export const linkTo = (kind, story) => (...args) => {
export const linkTo = (kind: string, story?: string) => (...args: string[]) => {
const resolver = valueOrCall(args);
navigate({
kind: resolver(kind),
story: resolver(story),
});
};

export const hrefTo = (kind, name) =>
export const hrefTo = (kind: string, name: string): Promise<string> =>
new Promise(resolve => {
resolve(generateUrl(toId(kind, name)));
});

const linksListener = e => {
const { sbKind: kind, sbStory: story } = e.target.dataset;
const linksListener = (e: SyntheticEvent<HTMLLinkElement>) => {
const { sbKind: kind, sbStory: story } = e.currentTarget.dataset;
if (kind || story) {
e.preventDefault();
navigate({ kind, story });
Expand All @@ -52,7 +60,7 @@ const off = () => {
}
};

export const withLinks = storyFn => {
export const withLinks = (storyFn: () => void) => {
on();
addons.getChannel().once(STORY_CHANGED, off);
return storyFn();
Expand Down
2 changes: 1 addition & 1 deletion addons/links/src/react/components/link.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import addons from '@storybook/addons';

import { SELECT_STORY } from '@storybook/core-events';
import { mockChannel } from '../../preview.test';
import LinkTo from './link';
import LinkTo from './link.tsx';

jest.mock('@storybook/addons');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

import { navigate, hrefTo } from '../../preview';

Expand All @@ -9,48 +8,58 @@ import { navigate, hrefTo } from '../../preview';
// Cmd/Ctrl/Shift/Alt + Click should trigger default browser behaviour. Same applies to non-left clicks
const LEFT_BUTTON = 0;

const isPlainLeftClick = e =>
const isPlainLeftClick = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) =>
e.button === LEFT_BUTTON && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey;

const cancelled = (e, cb = () => {}) => {
const cancelled = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>, cb = (_e: any) => {}) => {
if (isPlainLeftClick(e)) {
e.preventDefault();
cb(e);
}
};

export default class LinkTo extends PureComponent {
constructor(...args) {
super(...args);
interface Props {
kind: string;
story: string;
children: React.ReactNode;
}

this.state = {
href: '/',
};
interface State {
href: string;
}

this.handleClick = this.handleClick.bind(this);
}
export default class LinkTo extends PureComponent<Props, State> {
defaultProps: Props = {
kind: null,
story: null,
children: undefined,
};

state: State = {
href: '/',
};

componentDidMount() {
this.updateHref();
}

componentDidUpdate(prevProps) {
componentDidUpdate(prevProps: Props) {
const { kind, story } = this.props;

if (prevProps.kind !== kind || prevProps.story !== story) {
this.updateHref();
}
}

async updateHref() {
updateHref = async () => {
const { kind, story } = this.props;
const href = await hrefTo(kind, story);
this.setState({ href });
}
};

handleClick() {
handleClick = () => {
navigate(this.props);
}
};

render() {
const { kind, story, children, ...rest } = this.props;
Expand All @@ -63,15 +72,3 @@ export default class LinkTo extends PureComponent {
);
}
}

LinkTo.defaultProps = {
kind: null,
story: null,
children: undefined,
};

LinkTo.propTypes = {
kind: PropTypes.string,
story: PropTypes.string,
children: PropTypes.node,
};
1 change: 0 additions & 1 deletion addons/links/src/react/index.js

This file was deleted.

2 changes: 2 additions & 0 deletions addons/links/src/react/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import LinkTo from './components/link';
export default LinkTo;
1 change: 1 addition & 0 deletions addons/links/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'global';
13 changes: 13 additions & 0 deletions addons/links/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"types": ["webpack-env"]
},
"include": [
"src/**/*"
],
"exclude": [
"src/__tests__/**/*"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function integrityTest(integrityOptions, stories2snapsConverter) {
const possibleStoriesFiles = stories2snapsConverter.getPossibleStoriesFiles(fileName);
return !possibleStoriesFiles.some(fs.existsSync);
});
expect(abandonedStoryshots).toHaveLength(0);
expect(abandonedStoryshots.length).toBe(0);
});
});
}
Expand Down

0 comments on commit 6a1bebc

Please sign in to comment.