Skip to content

Commit 3ad3fff

Browse files
authored
Merge pull request #176 from storybookjs/yann/fix-missing-rules
Fix: Bring back non-categorized rules
2 parents 079456b + dea0b74 commit 3ad3fff

21 files changed

+50
-39
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ This plugin does not support MDX files.
169169
| [`storybook/csf-component`](./docs/rules/csf-component.md) | The component property should be set | | <ul><li>csf</li><li>flat/csf</li></ul> |
170170
| [`storybook/default-exports`](./docs/rules/default-exports.md) | Story files should have a default export | 🔧 | <ul><li>csf</li><li>flat/csf</li><li>recommended</li><li>flat/recommended</li></ul> |
171171
| [`storybook/hierarchy-separator`](./docs/rules/hierarchy-separator.md) | Deprecated hierarchy separator in title property | 🔧 | <ul><li>csf</li><li>flat/csf</li><li>recommended</li><li>flat/recommended</li></ul> |
172+
| [`storybook/meta-inline-properties`](./docs/rules/meta-inline-properties.md) | Meta should only have inline properties | | N/A |
172173
| [`storybook/no-redundant-story-name`](./docs/rules/no-redundant-story-name.md) | A story should not have a redundant name property | 🔧 | <ul><li>csf</li><li>flat/csf</li><li>recommended</li><li>flat/recommended</li></ul> |
173174
| [`storybook/no-stories-of`](./docs/rules/no-stories-of.md) | storiesOf is deprecated and should not be used | | <ul><li>csf-strict</li><li>flat/csf-strict</li></ul> |
174175
| [`storybook/no-title-property-in-meta`](./docs/rules/no-title-property-in-meta.md) | Do not define a title in meta | 🔧 | <ul><li>csf-strict</li><li>flat/csf-strict</li></ul> |

docs/rules/await-interactions.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
## Rule Details
1010

11-
Storybook provides an instrumented version of testing library in the [@storybook/testing-library](https://github.com/storybookjs/testing-library/) package. When [writing interactions](https://storybook.js.org/docs/react/essentials/interactions), make sure to **await** them, so that addon-interactions can intercept these helper functions and allow you to step through them when debugging.
11+
Storybook provides an instrumented version of testing library in the [@storybook/test](https://github.com/storybookjs/storybook/tree/next/code/lib/test) library (formerly available in [@storybook/testing-library](https://github.com/storybookjs/testing-library/) library). When [writing interactions](https://storybook.js.org/docs/essentials/interactions), make sure to **await** them, so that addon-interactions can intercept these helper functions and allow you to step through them when debugging.
1212

1313
Examples of **incorrect** code for this rule:
1414

1515
```js
16-
import { within, userEvent } from '@storybook/testing-library'
16+
import { within, userEvent } from '@storybook/test' // or from the legacy package "@storybook/testing-library";
1717

1818
MyStory.play = (context) => {
1919
const canvas = within(context.canvasElement)
@@ -25,7 +25,7 @@ MyStory.play = (context) => {
2525
Examples of **correct** code for this rule:
2626

2727
```js
28-
import { within, userEvent } from '@storybook/testing-library'
28+
import { within, userEvent } from '@storybook/test' // or from the legacy package "@storybook/testing-library";
2929

3030
MyStory.play = async (context) => {
3131
const canvas = within(context.canvasElement)

docs/rules/csf-component.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ While we encourage each CSF file to clearly correspond to a single component, it
3333

3434
## Further Reading
3535

36-
- [Automatic argType inference](https://storybook.js.org/docs/react/api/argtypes#automatic-argtype-inference)
36+
- [Automatic argType inference](https://storybook.js.org/docs/api/argtypes#automatic-argtype-inference)

docs/rules/default-exports.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## Rule Details
1010

11-
In [CSF](https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format), a story file should contain a _default export_ that describes the component, and _named exports_ that describe the stories. This rule enforces the definition of a default export in story files.
11+
In [CSF](https://storybook.js.org/docs/writing-stories#component-story-format), a story file should contain a _default export_ that describes the component, and _named exports_ that describe the stories. This rule enforces the definition of a default export in story files.
1212

1313
Examples of **incorrect** code for this rule:
1414

@@ -36,4 +36,4 @@ If you're using Storybook 6.5 and [CSF in MDX](https://github.com/storybookjs/st
3636

3737
## Further Reading
3838

39-
More information about defining stories here: https://storybook.js.org/docs/react/writing-stories/introduction#defining-stories
39+
More information about defining stories here: https://storybook.js.org/docs/writing-stories#defining-stories

docs/rules/meta-inline-properties.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Meta should only have inline properties (meta-inline-properties)
22

33
<!-- RULE-CATEGORIES:START -->
4+
5+
**Included in these configurations**: N/A
6+
47
<!-- RULE-CATEGORIES:END -->
58

69
## Rule Details

docs/rules/no-stories-of.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## Rule Details
1010

11-
Since Storybook 5.2, the [CSF format](https://storybook.js.org/docs/react/api/csf) was introduced and the `storiesOf` API has been deprecated.
11+
Since Storybook 5.2, the [CSF format](https://storybook.js.org/docs/api/csf) was introduced and the `storiesOf` API has been deprecated.
1212

1313
Examples of **incorrect** code for this rule:
1414

docs/rules/prefer-pascal-case.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## Rule Details
1010

11-
As a best practice, stories should be defined in [_PascalCase_](https://en.wiktionary.org/wiki/Pascal_case). This makes it simpler to visually differ stories to other code. Plus, it makes it simpler to define regexes for [non-story exports](https://storybook.js.org/docs/react/api/csf#non-story-exports).
11+
As a best practice, stories should be defined in [_PascalCase_](https://en.wiktionary.org/wiki/Pascal_case). This makes it simpler to visually differ stories to other code. Plus, it makes it simpler to define regexes for [non-story exports](https://storybook.js.org/docs/api/csf#non-story-exports).
1212

1313
Examples of **incorrect** code for this rule:
1414

@@ -24,4 +24,4 @@ export const PrimaryButton = {}
2424

2525
## Further Reading
2626

27-
More information about naming stories can be found here: https://storybook.js.org/docs/react/writing-stories/introduction#defining-stories
27+
More information about naming stories can be found here: https://storybook.js.org/docs/writing-stories#defining-stories

docs/rules/story-exports.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## Rule Details
1010

11-
In [CSF](https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format), a story file should contain a _default export_ that describes the component, and at _named exports_ that describe the stories. This rule enforces the definition of at least one named export in story files.
11+
In [CSF](https://storybook.js.org/docs/writing-stories#component-story-format), a story file should contain a _default export_ that describes the component, and at _named exports_ that describe the stories. This rule enforces the definition of at least one named export in story files.
1212

1313
Examples of **incorrect** code for this rule:
1414

@@ -38,4 +38,4 @@ This rule should only be applied in your `.stories.*` files. Please ensure you a
3838

3939
## Further Reading
4040

41-
More information about defining stories here: https://storybook.js.org/docs/react/writing-stories/introduction#defining-stories
41+
More information about defining stories here: https://storybook.js.org/docs/writing-stories#defining-stories

docs/rules/use-storybook-expect.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,29 @@
88

99
## Rule Details
1010

11-
Storybook provides a browser compatible version of Jest's expect via the [@storybook/jest](https://github.com/storybookjs/jest) library.
12-
When [writing interactions](https://storybook.js.org/docs/react/essentials/interactions) and asserting values, you should always use `expect` from the `@storybook/jest` library.
11+
Storybook provides a browser compatible version of `expect` via the [@storybook/test](https://github.com/storybookjs/storybook/tree/next/code/lib/test) library (formerly available in the legacy [@storybook/jest](https://github.com/storybookjs/jest) library).
12+
When [writing interactions](https://storybook.js.org/docs/essentials/interactions) and asserting values, you should always use `expect` from the `@storybook/test` library.
1313

1414
Examples of **incorrect** code for this rule:
1515

1616
```js
17-
Default.play = () => {
17+
Default.play = async () => {
1818
// using global expect from Jest. Will break on the browser
19-
expect(123).toEqual(123)
19+
await expect(123).toEqual(123)
2020
}
2121
```
2222

2323
Examples of **correct** code for this rule:
2424

2525
```js
26+
// correct import.
27+
import { expect } from '@storybook/test'
28+
// or this, which is now considered legacy
2629
import { expect } from '@storybook/jest'
2730

28-
Default.play = () => {
31+
Default.play = async () => {
2932
// using imported expect from storybook package
30-
expect(123).toEqual(123)
33+
await expect(123).toEqual(123)
3134
}
3235
```
3336

docs/rules/use-storybook-testing-library.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
## Rule Details
1010

11-
Storybook provides an instrumented version of testing library in the [@storybook/testing-library](https://github.com/storybookjs/testing-library/) package.
12-
When [writing interactions](https://storybook.js.org/docs/react/essentials/interactions), make sure to use the helper functions from `@storybook/testing-library`, so that addon-interactions can intercept these helper functions and allow you to step through them when debugging.
11+
Storybook provides an instrumented version of testing library in the [@storybook/test](https://github.com/storybookjs/storybook/tree/next/code/lib/test) library (formerly available in [@storybook/testing-library](https://github.com/storybookjs/testing-library/) library).
12+
When [writing interactions](https://storybook.js.org/docs/essentials/interactions), make sure to use the helper functions from `@storybook/test`, so that addon-interactions can intercept these helper functions and allow you to step through them when debugging.
1313

1414
Examples of **incorrect** code for this rule:
1515

@@ -26,6 +26,8 @@ Examples of **correct** code for this rule:
2626

2727
```js
2828
// correct import.
29+
import { within } from '@storybook/test'
30+
// or this, which is now considered legacy
2931
import { within } from '@storybook/testing-library'
3032

3133
Default.play = async (context) => {

lib/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import contextInPlayFunction from './rules/context-in-play-function'
1919
import csfComponent from './rules/csf-component'
2020
import defaultExports from './rules/default-exports'
2121
import hierarchySeparator from './rules/hierarchy-separator'
22+
import metaInlineProperties from './rules/meta-inline-properties'
2223
import noRedundantStoryName from './rules/no-redundant-story-name'
2324
import noStoriesOf from './rules/no-stories-of'
2425
import noTitlePropertyInMeta from './rules/no-title-property-in-meta'
@@ -49,6 +50,7 @@ export = {
4950
'csf-component': csfComponent,
5051
'default-exports': defaultExports,
5152
'hierarchy-separator': hierarchySeparator,
53+
'meta-inline-properties': metaInlineProperties,
5254
'no-redundant-story-name': noRedundantStoryName,
5355
'no-stories-of': noStoriesOf,
5456
'no-title-property-in-meta': noTitlePropertyInMeta,

tests/integrations/flat-config.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ describe('Integration with flat config', () => {
3030
}
3131

3232
const result = JSON.parse(
33-
cp.execSync(`${ESLINT} a.stories.tsx --max-warnings 1 --format=json`, {
33+
cp.execSync(`${ESLINT} a.stories.tsx --max-warnings 2 --format=json`, {
3434
encoding: 'utf-8',
3535
})
3636
)
3737
expect(result.length).toBe(1)
3838
expect(result[0].messages[0].messageId).toBe('shouldHaveStoryExport')
39+
expect(result[0].messages[1].messageId).toBe('metaShouldHaveInlineProperties')
3940
})
4041
})
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
const Input = () => 'This is an input component'
22

3-
export default {
4-
title: 'Input',
5-
component: Input,
6-
}
3+
const title = 'foo';
4+
export default { title }

tests/integrations/flat-config/eslint.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default [
66
files: ['**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '**/*.story.@(ts|tsx|js|jsx|mjs|cjs)'],
77
rules: {
88
'storybook/story-exports': 'warn',
9+
'storybook/meta-inline-properties': 'warn',
910
},
1011
},
1112
]

tests/integrations/legacy-config.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ describe('Integration with legacy config', () => {
3030
}
3131

3232
const result = JSON.parse(
33-
cp.execSync(`${ESLINT} a.stories.tsx --max-warnings 1 --format=json`, {
33+
cp.execSync(`${ESLINT} a.stories.tsx --max-warnings 2 --format=json`, {
3434
encoding: 'utf-8',
3535
})
3636
)
3737
expect(result.length).toBe(1)
3838
expect(result[0].messages[0].messageId).toBe('shouldHaveStoryExport')
39+
expect(result[0].messages[1].messageId).toBe('metaShouldHaveInlineProperties')
3940
})
4041
})

tests/integrations/legacy-config/.eslintrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
{
1010
"files": ["*.stories.@(ts|tsx|js|jsx|mjs|cjs)"],
1111
"rules": {
12-
"storybook/story-exports": "warn"
12+
"storybook/story-exports": "warn",
13+
"storybook/meta-inline-properties": "warn"
1314
}
1415
}
1516
]
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
const Input = () => 'This is an input component'
22

3-
export default {
4-
title: 'Input',
5-
component: Input,
6-
}
3+
const title = 'foo';
4+
export default { title }

tools/update-rules-list.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ const rulesList: TRulesList[] = Object.entries(rules)
2828
return [
2929
rule.name,
3030
createRuleLink(rule.name),
31-
rule.meta.docs.description,
31+
rule.meta.docs?.description || '',
3232
rule.meta.fixable ? emojiKey.fixable : '',
33-
rule.meta.docs.categories
34-
? `<ul>${rule.meta.docs.categories.map((c) => `<li>${c}</li><li>flat/${c}</li>`).join('')}</ul>`
35-
: '',
33+
rule.meta.docs?.excludeFromConfig
34+
? 'N/A'
35+
: rule.meta.docs?.categories
36+
? `<ul>${rule.meta.docs?.categories.map((c) => `<li>${c}</li><li>flat/${c}</li>`).join('')}</ul>`
37+
: '',
3638
]
3739
})
3840

tools/utils/categories.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ for (const categoryId of categoryIds) {
2424
categoriesConfig[categoryId].rules = []
2525

2626
for (const rule of rules) {
27-
const ruleCategories = rule.meta.docs.categories
27+
const ruleCategories = rule.meta.docs?.categories
2828
// Throw if rule does not have a category
2929
if (!ruleCategories?.length) {
3030
throw new Error(`Rule "${rule.ruleId}" does not have any category.`)
3131
}
3232

33-
if (ruleCategories.includes(categoryId)) {
33+
if (ruleCategories.includes(categoryId) && rule.meta.docs?.excludeFromConfig !== true) {
3434
categoriesConfig[categoryId].rules?.push(rule)
3535
}
3636
}

tools/utils/docs.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export const updateRulesDocs = async (rulesList: TRulesList[]) => {
106106

107107
const updatedDocFile = await format(overWriteRuleDocs(rule, ruleDocFile), {
108108
parser: 'markdown',
109-
...prettierConfig,
109+
...(await prettierConfig),
110110
})
111111

112112
await writeFile(ruleDocFilePath, updatedDocFile)

tools/utils/rules.ts

-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ const rules = fs
2828
meta,
2929
}
3030
})
31-
// We might have rules which are almost ready but should not be shipped
32-
.filter((rule) => !rule.meta.docs?.excludeFromConfig)
3331

3432
export type TRules = typeof rules
3533

0 commit comments

Comments
 (0)