Skip to content

Commit a2ce8d6

Browse files
authored
Merge pull request #241 from microsoftgraph/playground
Storybook integration (component playground)
2 parents 76763ba + 7aac41a commit a2ce8d6

17 files changed

+1823
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ testResults/junit.xml
3636
package-lock.json
3737

3838
*-css.ts
39+
40+
# storybook
41+
storybook-static/

.storybook/.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["@babel/preset-env", "@babel/preset-react"]
3+
}

.storybook/env.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const CLIENTID = 'ac77046c-156c-40f0-8507-3b5a58034582';
2+
export const GETPROVIDER_EVENT = 'mgt/getProvider';
3+
export const SETPROVIDER_EVENT = 'mgt/setProvider';

.storybook/main.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
module.exports = {
9+
presets: ['@storybook/addon-docs/preset'],
10+
stories: ['../stories/**/*.stories.(js|mdx)'],
11+
addons: [
12+
'@storybook/addon-a11y/register',
13+
'@storybook/addon-actions/register',
14+
'@storybook/addon-knobs/register',
15+
'@storybook/addon-links/register',
16+
'@storybook/addon-storysource/register'
17+
]
18+
};

.storybook/manager.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
import React, { useState } from 'react';
9+
import { addons, types } from '@storybook/addons';
10+
import { STORIES_CONFIGURED, STORY_MISSING } from '@storybook/core-events';
11+
import { AddonPanel } from '@storybook/components';
12+
import { useParameter, useChannel } from '@storybook/api';
13+
import { Providers, MsalProvider, LoginType, ProviderState } from '../dist/commonjs';
14+
import { CLIENTID, GETPROVIDER_EVENT, SETPROVIDER_EVENT } from './env';
15+
16+
const PARAM_KEY = 'signInAddon';
17+
const _allow_signin = false;
18+
19+
const msalProvider = new MsalProvider({
20+
clientId: CLIENTID,
21+
loginType: LoginType.Popup
22+
});
23+
24+
Providers.globalProvider = msalProvider;
25+
26+
const SignInPanel = () => {
27+
const value = useParameter(PARAM_KEY, null);
28+
29+
const [state, setState] = useState(Providers.globalProvider.state);
30+
31+
const emit = useChannel({
32+
STORY_RENDERED: id => {
33+
console.log('storyRendered', id);
34+
},
35+
[GETPROVIDER_EVENT]: params => {
36+
emitProvider(state);
37+
}
38+
});
39+
40+
const emitProvider = loginState => {
41+
emit(SETPROVIDER_EVENT, { state: loginState });
42+
};
43+
44+
Providers.onProviderUpdated(() => {
45+
setState(Providers.globalProvider.state);
46+
emitProvider(Providers.globalProvider.state);
47+
});
48+
49+
emitProvider(state);
50+
51+
return (
52+
<div>
53+
{_allow_signin ? (
54+
<mgt-login />
55+
) : (
56+
'All components are using mock data - sign in function will be available in a future release'
57+
)}
58+
</div>
59+
);
60+
};
61+
62+
addons.register('microsoft/graph-toolkit', storybookAPI => {
63+
storybookAPI.on(STORIES_CONFIGURED, (kind, story) => {
64+
if (storybookAPI.getUrlState().path === '/story/*') {
65+
storybookAPI.selectStory('mgt-login', 'login');
66+
}
67+
});
68+
storybookAPI.on(STORY_MISSING, (kind, story) => {
69+
storybookAPI.selectStory('mgt-login', 'login');
70+
});
71+
72+
const render = ({ active, key }) => (
73+
<AddonPanel active={active} key={key}>
74+
<SignInPanel />
75+
</AddonPanel>
76+
);
77+
78+
addons.add('mgt/sign-in', {
79+
type: types.PANEL,
80+
title: 'Sign In',
81+
render,
82+
paramKey: PARAM_KEY
83+
});
84+
});

.storybook/preview.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
/* global window */
9+
10+
import { configure, addParameters, setCustomElements } from '@storybook/web-components';
11+
import customElements from '../custom-elements.json';
12+
import '../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js';
13+
import theme from './theme';
14+
import '../dist/es6/components/mgt-login/mgt-login.js';
15+
16+
setCustomElements(customElements);
17+
18+
addParameters({
19+
docs: {
20+
iframeHeight: '200px'
21+
},
22+
options: {
23+
// disable keyboard shortcuts because they interfere with the stories
24+
enableShortcuts: false,
25+
theme
26+
}
27+
});
28+
29+
// force full reload to not reregister web components
30+
const req = require.context('../stories', true, /\.stories\.(js|mdx)$/);
31+
configure(req, module);
32+
if (module.hot) {
33+
module.hot.accept(req.id, () => {
34+
const currentLocationHref = window.location.href;
35+
window.history.pushState(null, null, currentLocationHref);
36+
window.location.reload();
37+
});
38+
}

.storybook/signInAddon.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import addons, { makeDecorator } from '@storybook/addons';
2+
import { Providers } from '../dist/es6/Providers';
3+
import { ProviderState } from '../dist/es6/providers/IProvider';
4+
import { MsalProvider } from '../dist/es6/providers/MsalProvider';
5+
import { MockProvider } from '../dist/es6/mock/MockProvider';
6+
import { CLIENTID, SETPROVIDER_EVENT, GETPROVIDER_EVENT } from './env';
7+
8+
const _allow_signin = false;
9+
10+
export const withSignIn = makeDecorator({
11+
name: `withSignIn`,
12+
parameterName: 'myParameter',
13+
skipIfNoParametersOrOptions: false,
14+
wrapper: (getStory, context, { parameters }) => {
15+
const mockProvider = new MockProvider(true);
16+
17+
const channel = addons.getChannel();
18+
19+
channel.on(SETPROVIDER_EVENT, params => {
20+
if (_allow_signin) {
21+
const currentProvider = Providers.globalProvider;
22+
if (params.state === ProviderState.SignedIn && (!currentProvider || currentProvider === mockProvider)) {
23+
Providers.globalProvider = new MsalProvider({
24+
clientId: CLIENTID
25+
});
26+
} else if (params.state !== ProviderState.SignedIn && currentProvider !== mockProvider) {
27+
Providers.globalProvider = mockProvider;
28+
}
29+
} else {
30+
Providers.globalProvider = mockProvider;
31+
}
32+
});
33+
34+
// Our simple API above simply sets the notes parameter to a string,
35+
// which we send to the channel
36+
channel.emit(GETPROVIDER_EVENT, { type: 'getProvider' });
37+
// we can also add subscriptions here using channel.on('eventName', callback);
38+
39+
return getStory(context);
40+
}
41+
});

.storybook/theme.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { create } from '@storybook/theming/create';
2+
3+
export default create({
4+
base: 'light',
5+
6+
// colorPrimary: 'hotpink',
7+
// colorSecondary: 'deepskyblue',
8+
9+
// UI
10+
// appBg: 'white',
11+
// appContentBg: 'silver',
12+
// appBorderColor: 'grey',
13+
// appBorderRadius: 4,
14+
15+
// Typography
16+
// fontBase: '"Open Sans", sans-serif',
17+
// fontCode: 'monospace',
18+
19+
// Text colors
20+
// textColor: 'black',
21+
// textInverseColor: 'rgba(255,255,255,0.9)',
22+
23+
// Toolbar default and active colors
24+
// barTextColor: 'silver',
25+
// barSelectedColor: 'black',
26+
// barBg: 'hotpink',
27+
28+
// Form colors
29+
// inputBg: 'white',
30+
// inputBorder: 'silver',
31+
// inputTextColor: 'black',
32+
// inputBorderRadius: 4,
33+
34+
brandTitle: 'Microsoft Graph Toolkit',
35+
brandUrl: 'https://aka.ms/mgt'
36+
});

0 commit comments

Comments
 (0)