UNPKG

6.2 kBMarkdownView Raw
1# @fluentui/eslint-plugin
2
3**ESLint configuration and custom rules for Fluent UI**
4
5## Configs
6
7Usage: in your [ESLint config file](https://eslint.org/docs/user-guide/configuring), add `{ "extends": ["plugin:@fluentui/<name>"] }` or `{ "extends": ["plugin:@fluentui/eslint-plugin/<name>"] }` (the two are equivalent).
8
9- `react`: react specific configuration for fluentui vNext
10- `node`: node specific configuration for fluentui vNext
11- `react--legacy`: react specific configuration for fluentui v7,8
12- `node--legacy`: node specific configuration for fluentui v7,8
13- `react-northstar`: For `@fluentui/react-northstar` and related packages
14- `imports`: auto import statements sorting configuration
15
16Helpers for customizing configuration are exported under a `configHelpers` object.
17
18## Rules
19
20### `ban-context-export`
21
22Exporting context objects as a part of the public API can lead to unexpected usages of context by customers and might
23impede future refactoring. To allow customers use context while encapsulating our internals correctly, the developer
24should export a provider and hook.
25
26**❌ Don't**
27
28```ts
29// src/context.ts
30import * as React from 'react';
31export const MyContext = React.createContext();
32
33// src/index.ts
34export { MyContext } from './context';
35```
36
37**✅ Do**
38
39```ts
40// src/context.ts
41import * as React from 'react';
42const MyContext = React.createContext();
43export const MyContextProvider = MyContext.Provider;
44export const useMyContext = () => React.useContext(MyContext);
45
46// src/index.ts
47export { MyContextProvider, useMyContext } from './context';
48```
49
50### `ban-imports`
51
52Ban importing or re-exporting from certain paths or modules. You can either ban the entire path, or only certain names. (Inspired by TSLint's [`import-blacklist`](https://palantir.github.io/tslint/rules/import-blacklist/).)
53
54Requires one or more options objects. Either `path` or `pathRegex` is required.
55
56- `path` (`string`): Path or module to ban importing from (non-regex)
57- `pathRegex` (`string`): Regex for path or module to ban importing from
58- `names` (`(string | { regex: string })[]`, optional): If provided, only ban imports of these names and/or regular expressions. Otherwise, ban all imports from the path.
59- `message` (`string[]`, optional): Custom message to show with errors
60
61Example:
62
63```
64"@fluentui/ban-imports": [
65 "error",
66 { "path": "lodash" },
67 { "path": "foo", "names": ["bar", { "regex": "^baz" }] },
68 { "pathRegex": "^\.", message: "no relative imports" },
69 { "pathRegex": "^\.\./(foo|bar)$", "names": ["baz"] }
70]
71```
72
73### `deprecated-keyboard-event-props`
74
75Prevent using deprecated `KeyboardEvent` props `which` and `keyCode`, and recommend using `@fluentui/keyboard-key` instead.
76
77### `max-len`
78
79Enforces max line length, more performantly than [ESLint's `max-len`](https://eslint.org/docs/rules/max-len).
80
81This rule is significantly faster than the default `max-len` rule because it **does not** support:
82
83- Expanding tabs (only handles spaces for indentation)
84- Multi-byte unicode characters (they will be counted as multiple characters)
85- Extra options for handling comments, strings, or URLs
86
87(Skipping these extra features lets us do a basic string length check before running any regular expressions or other extra logic, which makes the huge majority of line length checks very fast.)
88
89#### Options
90
91The rule requires an options object containing:
92
93- `max` (required): the maximum line length
94- `ignorePatterns` (optional): ignore the line if it matches any of these regular expressions
95
96### `no-global-react`
97
98Ban references to the `React` global namespace (in favor of explicitly importing React). Implicit global references cause problems for API Extractor and potentially other tools.
99
100### `no-restricted-imports`
101
102Prevents imports from `forbidden` packages. If a corresponding `preferred` import is provided, the lint error will be automatically fixable.
103
104**Example Configuration:**
105
106```
107"@fluentui/no-restricted-imports": [
108 'error',
109 {
110 paths: [
111 {
112 forbidden: ['@fluentui/react-theme', '@griffel/react`],
113 preferred: '@fluentui/react-components',
114 },
115 ],
116 },
117 ],
118```
119
120**❌ Don't**
121
122```ts
123import * as React from 'react';
124import { webDarkTheme } from '@fluentui/react-theme';
125import { makeStyles } from '@griffel/react';
126```
127
128**✅ Do**
129
130```ts
131import * as React from 'react';
132import { makeStyles, webDarkTheme } from '@fluentui/react-components';
133```
134
135### `no-tslint-comments`
136
137Ban `tslint:disable` and `tslint:enable` comments.
138
139### `no-visibility-modifiers`
140
141Prevent visibility modifiers (`public`, `protected`, `private`) from being specified on class members/methods.
142
143Used in Fluent UI only by [`@fluentui/react-northstar`](https://aka.ms/fluent-ui), not `@fluentui/react`.
144
145### `no-context-default-value`
146
147Restricts usage of default values on React context creation. Imports should be provided to declare where the `createContext` function is coming from. For more information why this is necessary please consult [#23624](https://github.com/microsoft/fluentui/issues/23624)
148
149**Example Configuration:**
150
151```
152"@fluentui/no-context-default-value": [
153 "error",
154 {
155 imports: ["react", "@fluentui/react-context-selector"]
156 }
157]
158```
159
160**❌ Don't**
161
162```ts
163import * as React from 'react';
164const context = React.createContext({ someValue: undefined });
165```
166
167**✅ Do**
168
169```ts
170import * as React from 'react';
171const context = React.createContext(undefined);
172```
173
174### `ban-instanceof-html-element`
175
176Bans usage of `instanceof HTMLElement` binary expressions as they might cause problems on [multiple realms](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_realms) environments.
177
178The alternative is to use `isHTMLElement` helper method provided by `@fluentui/react-utilities` packages, since that method does the proper verifications to ensure proper instance comparison.
179
180**❌ Don't**
181
182```ts
183event.target instanceof HTMLElement;
184
185event.target instanceof HTMLInputElement;
186```
187
188**✅ Do**
189
190```ts
191import { isHTMLElement } from '@fluentui/react-components';
192
193isHTMLElement(event.target);
194
195isHTMLElement(event.target, { constructorName: 'HTMLInputElement' });
196```