-
-
Notifications
You must be signed in to change notification settings - Fork 111
/
preview.js
295 lines (279 loc) · 12.3 KB
/
preview.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
import { Amplitude, AmplitudeProvider } from '@amplitude/react-amplitude';
import { ThemeProvider } from '@emotion/react';
import '@storybook/addon-console'; // Automatically forwards all logs in the "Actions" panel - See https://github.com/storybookjs/storybook-addon-console
import { withTests } from '@storybook/addon-jest';
import { addDecorator } from '@storybook/react';
import { themes } from '@storybook/theming';
import find from 'lodash.find';
import React from 'react';
import { withNextRouter } from 'storybook-addon-next-router';
import { withPerformance } from 'storybook-addon-performance';
import '../src/components/appBootstrap/MultiversalGlobalExternalStyles'; // Import the same 3rd party libraries global styles as the pages/_app.tsx (for UI consistency)
import MultiversalGlobalStyles from '../src/components/appBootstrap/MultiversalGlobalStyles';
import { defaultLocale, getLangFromLocale, supportedLocales } from '../src/i18nConfig';
import amplitudeContext from '../src/stores/amplitudeContext';
import customerContext from '../src/stores/customerContext';
import { cypressContext } from '../src/stores/cypressContext';
import datasetContext from '../src/stores/datasetContext';
import i18nContext from '../src/stores/i18nContext';
import previewModeContext from '../src/stores/previewModeContext';
import quickPreviewContext from '../src/stores/quickPreviewContext';
import userConsentContext from '../src/stores/userConsentContext';
import { userSessionContext } from '../src/stores/userSessionContext';
import { getAmplitudeInstance } from '../src/utils/analytics/amplitude';
import '../src/utils/app/ignoreNoisyWarningsHacks';
import { initCustomerTheme } from '../src/utils/data/theme';
import i18nextLocize from '../src/utils/i18n/i18nextLocize';
import '../src/utils/icons/font-awesome';
import dataset from './mock/sb-dataset';
// Loads translations from local file cache (Locize)
const i18nTranslations = require('./.sb-translations.cache.json');
/**
* Story Global parameters for Storybook.
*
* Parameters are a set of static, named metadata about a story, typically used to control the behavior of Storybook features and addons.
* Parameters are applied at the top-level and act as default values.
*
* XXX They can be overridden per component and per story.
* See https://storybook.js.org/docs/react/writing-stories/parameters#rules-of-parameter-inheritance
*
* @see https://storybook.js.org/docs/react/writing-stories/parameters Parameters documentation
* @see https://github.com/storybookjs/storybook/blob/master/addons/actions/ADVANCED.md#configuration
* @see https://storybook.js.org/docs/react/essentials/backgrounds#configuration
*
* Theme:
* Configure Storybook theme, using dark by default.
* You can customise this behavior per story using parameters.
* Configuring the theme in "manager.js" didn't work out.
* Also, the "Docs" section is better using the "normal" theme, for readability.
*
* @see https://storybook.js.org/docs/react/configure/theming#global-theming Global theming
* @see https://storybook.js.org/docs/react/configure/theming#theming-docs Per story theming (parameter)
* @see https://storybook.js.org/docs/react/configure/theming#create-a-theme-quickstart Creating your own theme
*/
export const parameters = {
actions: {
argTypesRegex: '^on[A-Z].*',
/**
* Since Controls is built on the same engine as Storybook Docs, it can also show property documentation alongside your controls using the expanded parameter (defaults to false).
* We enable this for all stories by default.
*
* @see https://storybook.js.org/docs/react/essentials/controls#show-full-documentation-for-each-property
*/
expanded: true,
},
/**
* Configure stories argTypes for all stories.
*
* @deprecated Should not be used at the moment. See https://github.com/storybookjs/storybook/issues/11697
* @see https://storybook.js.org/docs/react/essentials/controls
*/
// argTypes: {},
/**
* Options.
* Couldn't find centralized documentation about it.
*/
options: {
/**
* @see https://storybook.js.org/docs/react/writing-stories/naming-components-and-hierarchy#sorting-stories
*/
storySort: {
method: 'alphabetical',
order: [
'App', // Should be first
'Next Right Now', // Should be second, if kept around
'Storybook Examples', // Should be last, if kept around
],
},
},
docs: {
theme: themes.normal,
},
};
/**
* Storybook ships with toolbar items to control the viewport and background the story renders in.
*
* Below, we extend the native toolbar to add a few more options, such as i18n.
* Those global types can then be used in decorators, for both global decorators and story decorators.
*
* @description toolbar.item Can be either an array of plain strings, or a MenuItem.
* See https://storybook.js.org/docs/react/essentials/toolbars-and-globals#advanced-usage
*
* @description toolbar.icon The icon the will be displayed in the top toolbar.
* See https://www.chromatic.com/component?appId=5a375b97f4b14f0020b0cda3&name=Basics%7CIcon&mode=interactive&buildNumber=13899
*
* @see https://storybook.js.org/docs/react/essentials/toolbars-and-globals
*/
export const globalTypes = {
locale: {
name: 'Locale',
description: 'Global locale for components',
defaultValue: defaultLocale,
toolbar: {
icon: 'globe', // See https://www.chromatic.com/component?appId=5a375b97f4b14f0020b0cda3&name=Basics%7CIcon&mode=interactive&buildNumber=13899
items: supportedLocales.map(locale => locale.name),
},
},
};
/**
* Allow to use Next.js Router in Storybook stories.
*
* If you need to customise a component/story, then you should see https://github.com/lifeiscontent/storybook-addon-next-router#as-a-decorator-in-a-story
* You'll need to specify the Router behavior per-story if the below default config doesn't suit you.
*
* @see https://github.com/lifeiscontent/storybook-addon-next-router#usage-in-previewjs
*/
addDecorator(
withNextRouter({
path: '/', // defaults to `/`
asPath: '/', // defaults to `/`
query: {}, // defaults to `{}`
// @formatter:off Disables odd WebStorm formatting for next line
push() {}, // defaults to using addon actions integration, can override any method in the router
// @formatter:on
}),
);
/**
* Decorators in .storybook/preview.js are useful to mock Stories.
*
* Like parameters, decorators can be defined globally, at the component level and for a single story (as we’ve seen).
* All decorators, defined at all levels that apply to a story will run whenever that story is rendered, in the order:
* - Global decorators, in the order they are defined
* - Component decorators, in the order they are defined
* - Story decorators, in the order they are defined.
*
* @see https://storybook.js.org/docs/react/writing-stories/decorators#context-for-mocking
* @see https://storybook.js.org/docs/react/writing-stories/decorators#global-decorators
*/
export const decorators = [
/**
* Mock variables used to initialize all stories.
*
* Mocking those ensures the components relying on them will work as expected.
* Basically, plays a similar role to _app and appBootstrap components (MultiversalAppBootstrap, etc.)
*
* About Amplitude analytics:
* - We don't want to track analytics using Amplitude.
* - All analytics is disabled when running a component through Storybook preview.
*
* About Google analytics, see ".storybook/main.js" documentation.
*
* @see https://storybook.js.org/docs/react/essentials/toolbars-and-globals#create-a-decorator Context and globals
*/
(Story, context) => {
// console.log('context', context) // Prints useful information about the Story's configuration
// Configure i18n. In Storybook, the locale can be set from the top Toolbar.
const locale = context?.globals?.locale || defaultLocale;
const lang = getLangFromLocale(locale);
// Applies i18next configuration with Locize backend
// Extra features like saveMissing, etc. will be disabled in production because Storybook doesn't have access to NEXT_PUBLIC_* environment variables there
// Although, they are configured in the same way as the Next.js app during development mode
i18nextLocize(lang, i18nTranslations);
const customer = find(dataset, { __typename: 'Customer' });
const customerTheme = initCustomerTheme(customer);
// console.log('customer', customer)
// console.log('customerTheme', customerTheme)
const customerRef = 'storybook'; // Fake customer ref
const amplitudeApiKey = ''; // Use invalid amplitude tracking key to force disable all amplitude analytics
const userConsent = {
isUserOptedOutOfAnalytics: true, // Disables all amplitude analytics tracking (even if a proper api key was being used)
hasUserGivenAnyCookieConsent: false,
};
const userId = 'storybook'; // Fake id (would avoid user tracking even if correct api key was being used)
const amplitudeInstance = getAmplitudeInstance({
customerRef,
iframeReferrer: null,
isInIframe: false,
lang,
locale,
userId,
userConsent: userConsent,
});
// Configure all providers, similarly to what being done by MultiversalAppBootstrap and BrowserPageBootstrap
return (
<datasetContext.Provider value={dataset}>
<quickPreviewContext.Provider value={false}>
<previewModeContext.Provider
value={{
isPreviewModeEnabled: false,
previewData: null,
}}
>
<i18nContext.Provider
value={{
lang: lang,
locale: locale,
}}
>
<customerContext.Provider value={customer}>
<MultiversalGlobalStyles customerTheme={customerTheme} />
<ThemeProvider theme={customerTheme}>
<AmplitudeProvider
amplitudeInstance={amplitudeInstance}
apiKey={amplitudeApiKey}
userId={userId}
>
<Amplitude
eventProperties={{
app: {
name: customerRef,
release: customerRef,
stage: `storybook-${process.env.NODE_ENV}`,
},
page: {
url: location.href,
path: location.pathname,
origin: location.origin,
},
customer: {
ref: customerRef,
},
lang: lang,
locale: locale,
}}
>
<cypressContext.Provider value={false}>
<amplitudeContext.Provider value={{ amplitudeInstance }}>
<userSessionContext.Provider value={null}>
<userConsentContext.Provider value={null}>
<Story />
</userConsentContext.Provider>
</userSessionContext.Provider>
</amplitudeContext.Provider>
</cypressContext.Provider>
</Amplitude>
</AmplitudeProvider>
</ThemeProvider>
</customerContext.Provider>
</i18nContext.Provider>
</previewModeContext.Provider>
</quickPreviewContext.Provider>
</datasetContext.Provider>
);
},
];
/**
* Enables storybook-addon-performance for all stories by default.
*
* @see https://github.com/atlassian-labs/storybook-addon-performance#installation
*/
addDecorator(withPerformance);
/**
* Configure Jest Storybook for all stories.
*
* Each story must define which test it's associated to, to show the associated tests results in the preview.
* See https://github.com/storybookjs/storybook/tree/master/addons/jest#usage
*
* @see https://github.com/storybookjs/storybook/tree/master/addons/jest
*/
try {
let testResults;
testResults = require('../.jest-test-results.json');
addDecorator(
withTests({
results: testResults,
}),
);
} catch (e) {
console.log(`Couldn't find ../.jest-test-results.json, Jest tests might not work properly.`)
}