Skip to content

Commit

Permalink
REMOVE tslint, and use eslint for everything (#6621)
Browse files Browse the repository at this point in the history
REMOVE tslint, and use eslint for everything
  • Loading branch information
shilman authored Apr 26, 2019
2 parents 5c3f196 + 1546f88 commit 8aae29d
Show file tree
Hide file tree
Showing 131 changed files with 4,621 additions and 4,109 deletions.
3 changes: 1 addition & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ docs/public
storybook-static
built-storybooks
lib/cli/test
scripts/storage
*.bundle.js
*.js.map
*.ts
*.tsx

!.remarkrc.js
!.babelrc.js
Expand Down
63 changes: 55 additions & 8 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
const error = 2;
const warn = 1;
const ignore = 0;

module.exports = {
root: true,
extends: [
'airbnb',
'plugin:jest/recommended',
'plugin:import/react-native',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/react',
'prettier/@typescript-eslint',
],
plugins: ['prettier', 'jest', 'import', 'react', 'jsx-a11y', 'json', 'html'],
parser: 'babel-eslint',
parserOptions: { ecmaVersion: 8, sourceType: 'module' },
plugins: [
'@typescript-eslint',
'prettier',
'jest',
'import',
'react',
'jsx-a11y',
'json',
'html',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 8,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
env: { es6: true, node: true, 'jest/globals': true },
settings: {
'import/core-modules': ['enzyme'],
'import/ignore': ['node_modules\\/(?!@storybook)'],
'import/resolver': { node: { extensions: ['.js', '.ts'] } },
'import/resolver': { node: { extensions: ['.js', '.ts', '.tsx', '.mjs'] } },
'html/html-extensions': ['.html'],
},
rules: {
Expand All @@ -30,6 +48,7 @@ module.exports = {
{
js: 'never',
ts: 'never',
tsx: 'never',
mjs: 'never',
},
],
Expand All @@ -42,11 +61,11 @@ module.exports = {
'**/example/**',
'*.js',
'**/*.test.js',
'**/*.stories.js',
'**/*.stories.*',
'**/scripts/*.js',
'**/stories/**/*.js',
'**/__tests__/**/*.js',
'**/.storybook/**/*.js',
'**/.storybook/**/*.*',
],
peerDependencies: true,
},
Expand Down Expand Up @@ -94,13 +113,21 @@ module.exports = {
error,
{ allow: ['__STORYBOOK_CLIENT_API__', '__STORYBOOK_ADDONS_CHANNEL__'] },
],
'@typescript-eslint/no-var-requires': ignore,
'@typescript-eslint/camelcase': ignore,
'@typescript-eslint/no-unused-vars': ignore,
'@typescript-eslint/explicit-member-accessibility': ignore,
'@typescript-eslint/explicit-function-return-type': ignore,
'@typescript-eslint/no-explicit-any': ignore, // would prefer to enable this
'@typescript-eslint/no-use-before-define': ignore, // this is duplicated
'@typescript-eslint/interface-name-prefix': ignore, // I don't agree
},
overrides: [
{
files: [
'**/__tests__/**',
'**/*.test.js',
'**/*.stories.js',
'**/*.test.*',
'**/*.stories.*',
'**/storyshots/**/stories/**',
'docs/src/new-components/lib/StoryLinkWrapper.js',
'docs/src/stories/**',
Expand All @@ -110,5 +137,25 @@ module.exports = {
},
},
{ files: '**/.storybook/config.js', rules: { 'global-require': ignore } },
{
files: ['**/*.stories.*'],
rules: {
'no-console': ignore,
},
},
{
files: ['**/*.tsx', '**/*.ts'],
rules: {
'react/prop-types': ignore, // we should use types
'no-dupe-class-members': ignore, // this is called overloads in typescript
},
},
{
files: ['**/*.d.ts'],
rules: {
'no-var': ignore, // this is how typescript works
'spaced-comment': ignore,
},
},
],
};
33 changes: 25 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,37 @@ yarn test --cli --update

In that case, please check the git diff before committing to make sure it only contains the intended changes.

#### 2c. Link `storybook` and any other required dependencies
#### 2c. Run Linter

If you want to test your own existing project using the GitHub version of storybook, you need to `link` the packages you use in your project.
We use eslint as a linter for all code (including typescript code).

```sh
cd app/react
yarn link
All you have to run is:

cd <your-project>
yarn link @storybook/react
```sh
yarn lint
```

# repeat with whichever other parts of the monorepo you are using.
It can be immensely helpful to get feedback in your editor, if you're using VsCode, you should install the `eslint` plugin and configure it with these settings:

```plaintext
"eslint.autoFixOnSave": true,
"eslint.packageManager": "yarn",
"eslint.options": {
"cache": true,
"cacheLocation": ".cache/eslint",
"extensions": [".js", ".jsx", ".mjs", ".json", ".ts", ".tsx"]
},
"eslint.validate": [
"javascript",
"javascriptreact",
{"language": "typescript", "autoFix": true },
{"language": "typescriptreact", "autoFix": true }
],
"eslint.alwaysShowStatus": true
```

This should enable auto-fix for all source files, and give linting warnings and errors within your editor.

### Reproductions

#### In the monorepo
Expand Down
2 changes: 1 addition & 1 deletion addons/a11y/src/components/A11YPanel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ThemeProvider, themes, convert } from '@storybook/theming';
import { STORY_RENDERED } from '@storybook/core-events';
import { ScrollArea } from '@storybook/components';

import { A11YPanel } from './A11YPanel.tsx';
import { A11YPanel } from './A11YPanel';
import { EVENTS } from '../constants';

function createApi() {
Expand Down
4 changes: 2 additions & 2 deletions addons/a11y/src/components/A11YPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { STORY_RENDERED } from '@storybook/core-events';
import { ActionBar, Icons, ScrollArea } from '@storybook/components';

import { AxeResults, Result } from 'axe-core';
import { API } from '@storybook/api';
import { Provider } from 'react-redux';
import { Report } from './Report';
import { Tabs } from './Tabs';
import { EVENTS } from '../constants';
import { API } from '@storybook/api';

import { Provider } from 'react-redux';
import store, { clearElements } from '../redux-config';

export enum RuleType {
Expand Down
5 changes: 3 additions & 2 deletions addons/a11y/src/components/ColorBlindness.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const ColorIcon = styled.span(
})
);

// tslint:disable-next-line:no-empty-interface
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface ColorBlindnessProps {}

interface ColorBlindnessState {
Expand Down Expand Up @@ -63,7 +63,8 @@ export class ColorBlindness extends Component<ColorBlindnessProps, ColorBlindnes
};

onVisibilityChange = (s: boolean) => {
if (this.state.expanded !== s) {
const { expanded } = this.state;
if (expanded !== s) {
this.setState({ expanded: s });
}
};
Expand Down
1 change: 1 addition & 0 deletions addons/a11y/src/components/Report/Elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ interface ElementsProps {
export const Elements: FunctionComponent<ElementsProps> = ({ elements, type }) => (
<ol>
{elements.map((element, index) => (
// eslint-disable-next-line react/no-array-index-key
<Element element={element} key={index} type={type} />
))}
</ol>
Expand Down
4 changes: 2 additions & 2 deletions addons/a11y/src/components/Report/HighlightToggle.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';
import { ThemeProvider, themes, convert } from '@storybook/theming';
import HighlightToggle from './HighlightToggle.tsx';
import store from '../../redux-config.tsx';
import HighlightToggle from './HighlightToggle';
import store from '../../redux-config';

function ThemedHighlightToggle(props) {
return (
Expand Down
64 changes: 37 additions & 27 deletions addons/a11y/src/components/Report/HighlightToggle.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { document } from 'global';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { styled, themes, convert } from '@storybook/theming';
Expand All @@ -10,6 +11,7 @@ import { IFRAME } from '../../constants';

export class HighlightedElementData {
originalOutline: string;

isHighlighted: boolean;
}

Expand Down Expand Up @@ -50,6 +52,7 @@ function getElementBySelectorPath(elementPath: string): HTMLElement {
}

function setElementOutlineStyle(targetElement: HTMLElement, outlineStyle: string): void {
// eslint-disable-next-line no-param-reassign
targetElement.style.outline = outlineStyle;
}

Expand All @@ -65,6 +68,7 @@ function areAllRequiredElementsHighlighted(
);
}).length;

// eslint-disable-next-line no-nested-ternary
return highlightedCount === 0
? CheckBoxStates.UNCHECKED
: highlightedCount === elementsToHighlight.length
Expand Down Expand Up @@ -99,34 +103,55 @@ class HighlightToggle extends Component<ToggleProps> {
private checkBoxRef = React.createRef<HTMLInputElement>();

componentDidMount() {
this.props.elementsToHighlight.forEach(element => {
const { elementsToHighlight, highlightedElementsMap } = this.props;
elementsToHighlight.forEach(element => {
const targetElement = getElementBySelectorPath(element.target[0]);
if (targetElement && !this.props.highlightedElementsMap.has(targetElement)) {
if (targetElement && !highlightedElementsMap.has(targetElement)) {
this.saveElementDataToMap(targetElement, false, targetElement.style.outline);
}
});
}

componentDidUpdate(prevProps: Readonly<ToggleProps>): void {
const { indeterminate } = this.props;
if (this.checkBoxRef.current) {
this.checkBoxRef.current.indeterminate = this.props.indeterminate;
this.checkBoxRef.current.indeterminate = indeterminate;
}
}

onToggle = (): void => {
const { elementsToHighlight, highlightedElementsMap } = this.props;
elementsToHighlight.forEach(element => {
const targetElement = getElementBySelectorPath(element.target[0]);
if (!highlightedElementsMap.has(targetElement)) {
return;
}
const { originalOutline } = highlightedElementsMap.get(targetElement);
const { isHighlighted } = highlightedElementsMap.get(targetElement);
const { isToggledOn } = this.props;
if ((isToggledOn && isHighlighted) || (!isToggledOn && !isHighlighted)) {
const addHighlight = !isToggledOn && !isHighlighted;
this.highlightRuleLocation(targetElement, addHighlight);
this.saveElementDataToMap(targetElement, addHighlight, originalOutline);
}
});
};

highlightRuleLocation(targetElement: HTMLElement, addHighlight: boolean): void {
const { highlightedElementsMap, type } = this.props;
if (!targetElement) {
return;
}

if (addHighlight) {
setElementOutlineStyle(targetElement, `${colorsByType[this.props.type]} dotted 1px`);
setElementOutlineStyle(targetElement, `${colorsByType[type]} dotted 1px`);
return;
}

if (this.props.highlightedElementsMap.has(targetElement)) {
if (highlightedElementsMap.has(targetElement)) {
setElementOutlineStyle(
targetElement,
this.props.highlightedElementsMap.get(targetElement).originalOutline
highlightedElementsMap.get(targetElement).originalOutline
);
}
}
Expand All @@ -136,40 +161,25 @@ class HighlightToggle extends Component<ToggleProps> {
isHighlighted: boolean,
originalOutline: string
): void {
const { addElement: localAddElement } = this.props;
const data: HighlightedElementData = new HighlightedElementData();
data.isHighlighted = isHighlighted;
data.originalOutline = originalOutline;
const payload = { element: targetElement, highlightedElementData: data };
this.props.addElement(payload);
localAddElement(payload);
}

onToggle = (): void => {
this.props.elementsToHighlight.forEach(element => {
const targetElement = getElementBySelectorPath(element.target[0]);
if (!this.props.highlightedElementsMap.has(targetElement)) {
return;
}
const originalOutline = this.props.highlightedElementsMap.get(targetElement).originalOutline;
const { isHighlighted } = this.props.highlightedElementsMap.get(targetElement);
const { isToggledOn } = this.props;
if ((isToggledOn && isHighlighted) || (!isToggledOn && !isHighlighted)) {
const addHighlight = !isToggledOn && !isHighlighted;
this.highlightRuleLocation(targetElement, addHighlight);
this.saveElementDataToMap(targetElement, addHighlight, originalOutline);
}
});
};

render() {
const { toggleId, elementsToHighlight, isToggledOn } = this.props;
return (
<Checkbox
ref={this.checkBoxRef}
id={this.props.toggleId}
id={toggleId}
type="checkbox"
aria-label="Highlight result"
disabled={!this.props.elementsToHighlight.length}
disabled={!elementsToHighlight.length}
onChange={this.onToggle}
checked={this.props.isToggledOn}
checked={isToggledOn}
/>
);
}
Expand Down
3 changes: 2 additions & 1 deletion addons/a11y/src/components/Report/Rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React, { FunctionComponent } from 'react';
import { styled } from '@storybook/theming';
import { Badge, Icons } from '@storybook/components';
import { CheckResult } from 'axe-core';
import { RuleType } from '../A11YPanel';
import { SizeMe } from 'react-sizeme';
import { RuleType } from '../A11YPanel';

const impactColors = {
minor: '#f1c40f',
Expand Down Expand Up @@ -112,6 +112,7 @@ export const Rules: FunctionComponent<RulesProps> = ({ rules }) => {
return (
<List>
{rules.map((rule, index) => (
// eslint-disable-next-line react/no-array-index-key
<Rule rule={rule} key={index} />
))}
</List>
Expand Down
Loading

1 comment on commit 8aae29d

@vercel
Copy link

@vercel vercel bot commented on 8aae29d Apr 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.