Skip to content

Commit 20be361

Browse files
tassoevanggazzo
andauthored
Chore: Enforce TypeScript on Storybook (RocketChat#22317)
Co-authored-by: Guilherme Gazzo <guilhermegazzo@gmail.com>
1 parent a0e5bb2 commit 20be361

30 files changed

Lines changed: 332 additions & 182 deletions

‎.github/workflows/build_and_test.yml‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,6 @@ jobs:
128128

129129
- name: Build Storybook to sanity check components
130130
run: npm run build-storybook ; rm -rf ./storybook-static
131-
env:
132-
NODE_OPTIONS: --max_old_space_size=8192
133131

134132

135133
# To reduce memory need during actual build, build the packages solely first
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React from 'react';
1+
import React, { ReactElement } from 'react';
22

33
import { MeteorProviderMock } from './mocks/providers';
44

5-
export const rocketChatDecorator = (fn) => {
5+
export const rocketChatDecorator = (storyFn: () => ReactElement): ReactElement => {
66
const linkElement = document.getElementById('theme-styles') || document.createElement('link');
77
if (linkElement.id !== 'theme-styles') {
88
require('../app/theme/client/main.css');
@@ -14,7 +14,8 @@ export const rocketChatDecorator = (fn) => {
1414
document.head.appendChild(linkElement);
1515
}
1616

17-
// eslint-disable-next-line import/no-unresolved
17+
/* eslint-disable @typescript-eslint/no-var-requires */
18+
/* eslint-disable-next-line */
1819
const { default: icons } = require('!!raw-loader!../private/public/icons.svg');
1920

2021
return <MeteorProviderMock>
@@ -25,12 +26,12 @@ export const rocketChatDecorator = (fn) => {
2526
`}</style>
2627
<div dangerouslySetInnerHTML={{ __html: icons }} />
2728
<div className='color-primary-font-color'>
28-
{fn()}
29+
{storyFn()}
2930
</div>
3031
</MeteorProviderMock>;
3132
};
3233

33-
export const fullHeightDecorator = (storyFn) =>
34+
export const fullHeightDecorator = (storyFn: () => ReactElement): ReactElement =>
3435
<div style={{
3536
display: 'flex',
3637
flexDirection: 'column',
@@ -39,7 +40,7 @@ export const fullHeightDecorator = (storyFn) =>
3940
{storyFn()}
4041
</div>;
4142

42-
export const centeredDecorator = (storyFn) =>
43+
export const centeredDecorator = (storyFn: () => ReactElement): ReactElement =>
4344
<div style={{
4445
display: 'flex',
4546
alignItems: 'center',

‎.storybook/helpers.js‎

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { useEffect, useState } from 'react';
22

3-
export const useAutoToggle = (initialValue = false, ms = 1000) => {
3+
export const useAutoToggle = (initialValue = false, ms = 1000): boolean => {
44
const [value, setValue] = useState(initialValue);
55

66
useEffect(() => {
77
const timer = setInterval(() => setValue((value) => !value), ms);
88

9-
return () => {
9+
return (): void => {
1010
clearInterval(timer);
1111
};
1212
}, [ms]);

‎.storybook/logo.svg.d.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const path: string;
2+
export = path;

‎.storybook/main.js‎

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
const path = require('path');
1+
const { resolve, relative, join } = require('path');
22

33
const webpack = require('webpack');
44

55
module.exports = {
66
stories: [
7-
'../app/**/*.stories.js',
8-
'../client/**/*.stories.js',
9-
'../ee/**/*.stories.js',
7+
'../app/**/*.stories.{js,tsx}',
8+
'../client/**/*.stories.{js,tsx}',
9+
'../ee/**/*.stories.{js,tsx}',
1010
],
1111
addons: [
1212
'@storybook/addon-essentials',
@@ -26,8 +26,8 @@ module.exports = {
2626
require('autoprefixer')(),
2727
require('postcss-url')({ url: ({ absolutePath, relativePath, url }) => {
2828
const absoluteDir = absolutePath.slice(0, -relativePath.length);
29-
const relativeDir = path.relative(absoluteDir, path.resolve(__dirname, '../public'));
30-
const newPath = path.join(relativeDir, url);
29+
const relativeDir = relative(absoluteDir, resolve(__dirname, '../public'));
30+
const newPath = join(relativeDir, url);
3131
return newPath;
3232
} }),
3333
],
@@ -50,24 +50,20 @@ module.exports = {
5050
{
5151
loader: 'ts-loader',
5252
options: {
53-
compilerOptions: {
54-
noEmit: false,
55-
},
53+
configFile: join(__dirname, '../tsconfig.webpack.json'),
5654
},
5755
},
5856
],
5957
});
6058

61-
config.resolve.extensions.push('.ts', '.tsx');
62-
6359
config.plugins.push(
6460
new webpack.NormalModuleReplacementPlugin(
6561
/^meteor/,
6662
require.resolve('./mocks/meteor.js'),
6763
),
6864
new webpack.NormalModuleReplacementPlugin(
6965
/(app)\/*.*\/(server)\/*/,
70-
require.resolve('./mocks/empty.js'),
66+
require.resolve('./mocks/empty.ts'),
7167
),
7268
);
7369

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import colorTokens from '@rocket.chat/fuselage-tokens/colors';
1+
import colorTokens from '@rocket.chat/fuselage-tokens/colors.json';
22
import { addons } from '@storybook/addons';
3-
import { create } from '@storybook/theming/create';
3+
import { create } from '@storybook/theming';
44

55
import manifest from '../package.json';
66
import logo from './logo.svg';
@@ -10,7 +10,7 @@ addons.setConfig({
1010
base: 'light',
1111
brandTitle: manifest.name,
1212
brandImage: logo,
13-
brandUrl: manifest.homepage,
13+
brandUrl: manifest.author.url,
1414
colorPrimary: colorTokens.n500,
1515
colorSecondary: colorTokens.b500,
1616
}),

‎.storybook/mocks/meteor.js‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ export const Meteor = {
55
isClient: true,
66
isServer: false,
77
_localStorage: window.localStorage,
8-
absoluteUrl: () => {},
8+
absoluteUrl: Object.assign(() => {}, {
9+
defaultOptions: {},
10+
}),
911
userId: () => {},
1012
Streamer: () => ({
1113
on: () => {},
@@ -16,8 +18,6 @@ export const Meteor = {
1618
call: () => {},
1719
};
1820

19-
Meteor.absoluteUrl.defaultOptions = {};
20-
2121
export const Tracker = {
2222
autorun: () => ({
2323
stop: () => {},
@@ -51,17 +51,17 @@ export const ReactiveDict = () => ({
5151
all: () => {},
5252
});
5353

54-
export const Template = () => ({
54+
export const Template = Object.assign(() => ({
5555
onCreated: () => {},
5656
onRendered: () => {},
5757
onDestroyed: () => {},
5858
helpers: () => {},
5959
events: () => {},
60+
}), {
61+
registerHelper: () => {},
62+
__checkName: () => {},
6063
});
6164

62-
Template.registerHelper = () => {};
63-
Template.__checkName = () => {};
64-
6565
export const Blaze = {
6666
Template,
6767
registerHelper: () => {},
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import i18next from 'i18next';
2-
import React from 'react';
2+
import React, { PropsWithChildren, ReactElement } from 'react';
33

4-
import { TranslationContext } from '../../client/contexts/TranslationContext';
4+
import { TranslationContext, TranslationContextValue } from '../../client/contexts/TranslationContext';
55
import ServerProvider from '../../client/providers/ServerProvider';
66

7-
let contextValue;
7+
let contextValue: TranslationContextValue;
88

9-
const getContextValue = () => {
9+
const getContextValue = (): TranslationContextValue => {
1010
if (contextValue) {
1111
return contextValue;
1212
}
@@ -26,8 +26,8 @@ const getContextValue = () => {
2626
initImmediate: false,
2727
});
2828

29-
const translate = (key, ...replaces) => {
30-
if (typeof replaces[0] === 'object') {
29+
const translate = (key: string, ...replaces: unknown[]): string => {
30+
if (typeof replaces[0] === 'object' && replaces[0] !== null) {
3131
const [options] = replaces;
3232
return i18next.t(key, options);
3333
}
@@ -42,7 +42,7 @@ const getContextValue = () => {
4242
});
4343
};
4444

45-
translate.has = (key) => key && i18next.exists(key);
45+
translate.has = (key: string): boolean => !!key && i18next.exists(key);
4646

4747
contextValue = {
4848
languages: [{
@@ -52,16 +52,17 @@ const getContextValue = () => {
5252
}],
5353
language: 'en',
5454
translate,
55+
loadLanguage: async (): Promise<void> => undefined,
5556
};
5657

5758
return contextValue;
5859
};
5960

60-
function TranslationProviderMock({ children }) {
61+
function TranslationProviderMock({ children }: PropsWithChildren<{}>): ReactElement {
6162
return <TranslationContext.Provider children={children} value={getContextValue()} />;
6263
}
6364

64-
export function MeteorProviderMock({ children }) {
65+
export function MeteorProviderMock({ children }: PropsWithChildren<{}>): ReactElement {
6566
return <ServerProvider>
6667
<TranslationProviderMock>
6768
{children}

0 commit comments

Comments
 (0)