Skip to content

Commit

Permalink
Merge pull request #5380 from gaetanmaisse/ts-migration/addon-cssreso…
Browse files Browse the repository at this point in the history
…urces

Migrate addon cssresources to TS
  • Loading branch information
ndelangen committed Jan 27, 2019
2 parents db3bf63 + 53a7fb5 commit 6f4cf1c
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 43 deletions.
6 changes: 3 additions & 3 deletions addons/cssresources/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { withCssResources } from '@storybook/addon-cssresources';
addDecorator(
withCssResources({
cssresources: [{
name: `bluetheme`,
id: `bluetheme`,
code: `<style>body { background-color: lightblue; }</style>`,
picked: false,
},
Expand All @@ -48,11 +48,11 @@ storiesOf('Addons|Cssresources', module)
.addDecorator(
withCssResources({
cssresources: [{
name: `fontawesome`,
id: `fontawesome`,
code: `<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"></link>`,
picked: true,
}, {
name: `whitetheme`,
id: `whitetheme`,
code: `<style>.fa { color: #fff }</style>`,
picked: true,
},
Expand Down
3 changes: 2 additions & 1 deletion addons/cssresources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
"license": "MIT",
"author": "nm123github",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@emotion/styled": "10.0.6",
"@storybook/addons": "5.0.0-alpha.9",
"@storybook/channels": "5.0.0-alpha.9",
"@storybook/components": "5.0.0-alpha.9",
"@storybook/core-events": "5.0.0-alpha.9",
"core-js": "^2.6.2",
Expand Down
5 changes: 5 additions & 0 deletions addons/cssresources/src/CssResource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface CssResource {
id: string;
code: string;
picked: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const ADDON_ID = 'storybook/cssresources';
export const PANEL_ID = `${ADDON_ID}/panel`;
export const PARAM_KEY = 'cssresources';

export default {
export const EVENTS = {
SET: `${ADDON_ID}:set`,
UNSET: `${ADDON_ID}:unset`,
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { SyntaxHighlighter } from '@storybook/components';
import events, { STORY_CHANGED } from '@storybook/core-events';
import { EVENTS, PARAM_KEY } from './constants';
import { Channel } from '@storybook/channels';
import { CssResource } from './CssResource';
import { bool, func, shape } from 'prop-types';

import { STORY_CHANGED } from '@storybook/core-events';
import EVENTS, { PARAM_KEY } from './constants';
interface CssResourcePanelProps {
active: boolean;
channel: Channel;
api: {
emit: (event: any, data: any) => void;
on: (event: events, callback: (data: any) => void) => void;
off: (event: events, callback: (data: any) => void) => void;
getQueryParam: () => void;
getParameters: (id: string, paramKey: string) => any;
setQueryParams: () => void;
};
}

interface CssResourcePanelState {
list: CssResource[];
}

export default class CssResourcePanel extends Component {
constructor(props) {
export class CssResourcePanel extends Component<CssResourcePanelProps, CssResourcePanelState> {
constructor(props: CssResourcePanelProps) {
super(props);

this.state = {
Expand All @@ -24,26 +42,26 @@ export default class CssResourcePanel extends Component {
api.off(STORY_CHANGED, this.onStoryChange);
}

onStoryChange = id => {
onStoryChange = (id: string) => {
const { api } = this.props;
const list = api.getParameters(id, PARAM_KEY);
const list = api.getParameters(id, PARAM_KEY) as CssResource[];

if (list) {
const picked = list.filter(res => res.picked);
this.setState({ list }, () => this.emit(picked));
}
};

onChange = event => {
onChange = (event: any) => {
const { list: oldList } = this.state;
const list = oldList.map(i => ({
...i,
picked: i.id === event.target.id ? event.target.checked : i.picked,
}));
this.setState({ list }, () => this.emit(list.filter(res => res.picked)));
this.setState({ list }, () => this.emit(list.filter((res: any) => res.picked)));
};

emit(list) {
emit(list: CssResource[]) {
const { api } = this.props;
api.emit(EVENTS.SET, list);
}
Expand Down Expand Up @@ -73,16 +91,16 @@ export default class CssResourcePanel extends Component {
}
}

CssResourcePanel.propTypes = {
active: PropTypes.bool.isRequired,
channel: PropTypes.shape({
on: PropTypes.func,
emit: PropTypes.func,
removeListener: PropTypes.func,
(CssResourcePanel as any).propTypes = {
active: bool.isRequired,
channel: shape({
on: func,
emit: func,
removeListener: func,
}).isRequired,
api: PropTypes.shape({
on: PropTypes.func,
getQueryParam: PropTypes.func,
setQueryParams: PropTypes.func,
api: shape({
on: func,
getQueryParam: func,
setQueryParams: func,
}).isRequired,
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { document } from 'global';
import addons, { makeDecorator } from '@storybook/addons';
import EVENTS, { PARAM_KEY } from './constants';
import { addons, makeDecorator } from '@storybook/addons';
import { EVENTS, PARAM_KEY } from './constants';

const changeMediaAttribute = (element, enabled) => {
const changeMediaAttribute = (element: HTMLElement, enabled: boolean) => {
const current = element.getAttribute('media');
if ((enabled && !current) || (!enabled && current === 'max-width: 1px')) {
// don't do anything
Expand All @@ -19,29 +19,33 @@ const changeMediaAttribute = (element, enabled) => {
element.setAttribute('media', value);
}
};
const createElement = (id, code) => {
const element = document.createElement('div');

const createElement = (id: string, code: string): HTMLDivElement => {
const element: HTMLDivElement = document.createElement('div');
element.setAttribute('id', `storybook-addon-resource_${id}`);
element.innerHTML = code;
return element;
};
const getElement = (id, code) => {
const found = document.querySelector(`[id="storybook-addon-resource_${id}"]`);

const getElement = (id: string, code: string) => {
const found: Element = document.querySelector(`[id="storybook-addon-resource_${id}"]`);
return { element: found || createElement(id, code), created: !found };
};
const updateElement = (id, code, value) => {

const updateElement = (id: string, code: string, value: boolean) => {
const { element, created } = getElement(id, code);
const tags = [...element.querySelectorAll('link'), ...element.querySelectorAll('style')];

tags.forEach(child => changeMediaAttribute(child, value));
element.querySelectorAll('link').forEach(child => changeMediaAttribute(child, value));
element.querySelectorAll('style').forEach(child => changeMediaAttribute(child, value));

if (created) {
document.body.appendChild(element);
}
};

const list = [];
const setResources = resources => {
const list: any[] = [];

const setResources = (resources: Array<{ code: string; id: string }>) => {
const added = resources.filter(i => !list.find(r => r.code === i.code));
const removed = list.filter(i => !resources.find(r => r.code === i.code));

Expand All @@ -63,7 +67,7 @@ export const withCssResources = makeDecorator({
skipIfNoParametersOrOptions: true,
allowDeprecatedUsage: false,

wrapper: (getStory, context, { options, parameters }) => {
wrapper: (getStory: any, context: any, { options, parameters }: any) => {
const storyOptions = parameters || options;
addons.getChannel().on(EVENTS.SET, setResources);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React from 'react';
import addons, { types } from '@storybook/addons';
import { addons, types } from '@storybook/addons';

import { ADDON_ID, PANEL_ID } from './constants';

import CssResourcePanel from './css-resource-panel';
import { CssResourcePanel } from './css-resource-panel';

addons.register(ADDON_ID, api => {
const channel = addons.getChannel();
// Need to cast as any as it's not matching Addon type, to investigate
addons.add(PANEL_ID, {
type: types.PANEL,
title: 'CSS resources',
// eslint-disable-next-line react/prop-types
render: ({ active, key }) => (
render: ({ active, key }: any) => (
<CssResourcePanel key={key} channel={channel} api={api} active={active} />
),
});
} as any);
});
3 changes: 3 additions & 0 deletions addons/cssresources/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// TODO: following packages need definition files or a TS migration
declare module '@storybook/components';
declare module 'global';
13 changes: 13 additions & 0 deletions addons/cssresources/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__/**/*"
]
}

0 comments on commit 6f4cf1c

Please sign in to comment.