Skip to content

Commit

Permalink
[code-infra] Add "use client" directive to files with React APIs (#45036
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Janpot authored Jan 21, 2025
1 parent 57639f9 commit 4f872d6
Show file tree
Hide file tree
Showing 20 changed files with 84 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,21 @@ module.exports = /** @type {Config} */ ({
'react/prop-types': 'off',
},
},
{
files: ['packages/*/src/*/*.?(c|m)[jt]s?(x)'],
excludedFiles: [
'*.spec.*',
'*.test.*',
// deprecated library
'**/mui-base/**/*',
'**/mui-joy/**/*',
// used internally, not used on app router yet
'**/mui-docs/**/*',
],
rules: {
'material-ui/disallow-react-api-in-server-components': 'error',
},
},
{
files: ['packages/*/src/**/*.?(c|m)[jt]s?(x)'],
excludedFiles: '*.spec.*',
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin-material-ui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ module.exports.rules = {
'no-empty-box': require('./rules/no-empty-box'),
'no-styled-box': require('./rules/no-styled-box'),
'straight-quotes': require('./rules/straight-quotes'),
'disallow-react-api-in-server-components': require('./rules/disallow-react-api-in-server-components'),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module.exports = {
create(context) {
let hasUseClientDirective = false;
const apis = new Set([
'useState',
'useEffect',
'useLayoutEffect',
'useReducer',
'useTransition',
'createContext',
]);
return {
Program(node) {
hasUseClientDirective = node.body.some(
(statement) =>
statement.type === 'ExpressionStatement' &&
statement.expression.type === 'Literal' &&
statement.expression.value === 'use client',
);
},
CallExpression(node) {
if (
!hasUseClientDirective &&
node.callee.type === 'MemberExpression' &&
node.callee.object.name === 'React' &&
apis.has(node.callee.property.name)
) {
context.report({
node,
message: `Using 'React.${node.callee.property.name}' is forbidden if the file doesn't have a 'use client' directive.`,
fix(fixer) {
const sourceCode = context.getSourceCode();
if (
sourceCode.text.includes('"use server"') ||
sourceCode.text.includes("'use server'")
) {
return null;
}

const firstToken = sourceCode.ast.body[0];
return fixer.insertTextBefore(firstToken, "'use client';\n");
},
});
}
},
};
},
meta: {
fixable: 'code',
},
};
1 change: 1 addition & 0 deletions packages/mui-lab/src/Timeline/TimelineContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

type ButtonPositionClassName = string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import type { ButtonGroupProps } from './ButtonGroup';

Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/Dialog/DialogContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

interface DialogContextValue {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import type { FormControlProps } from './FormControl';

Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/Hidden/withWidth.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
import getDisplayName from '@mui/utils/getDisplayName';
Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/RadioGroup/RadioGroupContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

export interface RadioGroupContextValue {
Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/Step/StepContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

export interface StepContextType {
Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/Stepper/StepperContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

export interface StepperContextType {
Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/Table/Tablelvl2Context.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

type ToggleButtonPositionClassName = string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import type { ToggleButtonGroupProps } from './ToggleButtonGroup';

Expand Down
1 change: 1 addition & 0 deletions packages/mui-private-theming/src/useTheme/ThemeContext.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';

const ThemeContext = React.createContext(null);
Expand Down
1 change: 1 addition & 0 deletions packages/mui-styles/src/StylesProvider/StylesProvider.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
import { exactProp } from '@mui/utils';
Expand Down
1 change: 1 addition & 0 deletions packages/mui-styles/src/makeStyles/makeStyles.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import { getDynamicStyles } from 'jss';
import mergeClasses from '../mergeClasses';
Expand Down
1 change: 1 addition & 0 deletions packages/mui-system/src/RtlProvider/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';

Expand Down
1 change: 1 addition & 0 deletions packages/mui-system/src/cssVars/createCssVarsProvider.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
import { GlobalStyles } from '@mui/styled-engine';
Expand Down

0 comments on commit 4f872d6

Please sign in to comment.