Skip to content

Commit a2e8a13

Browse files
authored
Create eslint rule suggesting useLayoutEffect from @react-aria (#2668)
1 parent d80c236 commit a2e8a13

File tree

10 files changed

+49
-10
lines changed

10 files changed

+49
-10
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ module.exports = {
169169
// custom rules
170170
'rulesdir/sort-imports': [ERROR],
171171
'rulesdir/imports': [ERROR],
172+
'rulesdir/useLayoutEffectRule': [ERROR],
172173

173174
// jsx-a11y rules
174175
'jsx-a11y/accessible-emoji': ERROR,

bin/useLayoutEffectRule.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2020 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
module.exports = function (context) {
14+
return {
15+
ImportDeclaration(node) {
16+
const source = node.source.value;
17+
if (source === '@react-aria/utils' || source === './useLayoutEffect' || source === './') {
18+
return;
19+
}
20+
const importSpecifiers = node.specifiers.filter(specifier => specifier.type === 'ImportSpecifier');
21+
const getName = specifier => specifier.local.name;
22+
importSpecifiers.map(
23+
(item) => {
24+
let itemName = getName(item);
25+
if (itemName === 'useLayoutEffect') {
26+
context.report(node, 'Please use useLayoutEffect from @react-aria/utils instead.');
27+
}
28+
}
29+
);
30+
}
31+
};
32+
};

packages/@react-aria/dnd/src/useDrop.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {DragEvent, HTMLAttributes, RefObject, useLayoutEffect, useRef, useState} from 'react';
13+
import {DragEvent, HTMLAttributes, RefObject, useRef, useState} from 'react';
1414
import * as DragManager from './DragManager';
1515
import {DragTypes, readFromDataTransfer} from './utils';
1616
import {DROP_EFFECT_TO_DROP_OPERATION, DROP_OPERATION, DROP_OPERATION_ALLOWED, DROP_OPERATION_TO_DROP_EFFECT} from './constants';
1717
import {DropActivateEvent, DropEnterEvent, DropEvent, DropExitEvent, DropMoveEvent, DropOperation, DragTypes as IDragTypes} from '@react-types/shared';
18+
import {useLayoutEffect} from '@react-aria/utils';
1819
import {useVirtualDrop} from './useVirtualDrop';
1920

2021
interface DropOptions {

packages/@react-aria/dnd/src/useDroppableCollection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import {Collection, DropEvent, DropOperation, DroppableCollectionProps, DropPosi
1414
import * as DragManager from './DragManager';
1515
import {DroppableCollectionState} from '@react-stately/dnd';
1616
import {getTypes} from './utils';
17-
import {HTMLAttributes, Key, RefObject, useCallback, useEffect, useLayoutEffect, useRef} from 'react';
18-
import {mergeProps} from '@react-aria/utils';
17+
import {HTMLAttributes, Key, RefObject, useCallback, useEffect, useRef} from 'react';
18+
import {mergeProps, useLayoutEffect} from '@react-aria/utils';
1919
import {setInteractionModality} from '@react-aria/interactions';
2020
import {useAutoScroll} from './useAutoScroll';
2121
import {useDrop} from './useDrop';

packages/@react-aria/ssr/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"url": "https://github.com/adobe/react-spectrum"
1818
},
1919
"dependencies": {
20-
"@babel/runtime": "^7.6.2"
20+
"@babel/runtime": "^7.6.2",
21+
"@react-aria/utils": "^3.10.0"
2122
},
2223
"peerDependencies": {
2324
"react": "^16.8.0 || ^17.0.0-rc.1"

packages/@react-aria/ssr/src/SSRProvider.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import React, {ReactNode, useContext, useLayoutEffect, useMemo, useState} from 'react';
13+
import React, {ReactNode, useContext, useMemo, useState} from 'react';
14+
import {useLayoutEffect} from '@react-aria/utils';
1415

1516
// To support SSR, the auto incrementing id counter is stored in a context. This allows
1617
// it to be reset on every request to ensure the client and server are consistent.

packages/@react-aria/tabs/src/useTabPanel.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import {AriaTabPanelProps} from '@react-types/tabs';
1414
import {generateId} from './utils';
1515
import {getFocusableTreeWalker} from '@react-aria/focus';
16-
import {HTMLAttributes, RefObject, useLayoutEffect, useState} from 'react';
17-
import {mergeProps, useLabels} from '@react-aria/utils';
16+
import {HTMLAttributes, RefObject, useState} from 'react';
17+
import {mergeProps, useLabels, useLayoutEffect} from '@react-aria/utils';
1818
import {TabListState} from '@react-stately/tabs';
1919

2020
interface TabPanelAria {

packages/@react-aria/utils/test/useObjectRef.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import React, {useEffect, useLayoutEffect} from 'react';
13+
import React, {useEffect} from 'react';
1414
import {render, screen} from '@testing-library/react';
1515
import {renderHook} from '@testing-library/react-hooks';
16+
import {useLayoutEffect} from '@react-aria/utils';
1617
import {useObjectRef} from '../';
1718

1819
describe('useObjectRef', () => {

packages/@react-spectrum/autocomplete/src/SearchAutocomplete.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {MobileSearchAutocomplete} from './MobileSearchAutocomplete';
2424
import {Placement} from '@react-types/overlays';
2525
import {Popover} from '@react-spectrum/overlays';
2626
import {ProgressCircle} from '@react-spectrum/progress';
27-
import React, {forwardRef, InputHTMLAttributes, RefObject, useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';
27+
import React, {forwardRef, InputHTMLAttributes, RefObject, useCallback, useEffect, useRef, useState} from 'react';
2828
import searchStyles from '@adobe/spectrum-css-temp/components/search/vars.css';
2929
import {SpectrumSearchAutocompleteProps} from '@react-types/autocomplete';
3030
import styles from '@adobe/spectrum-css-temp/components/inputgroup/vars.css';
@@ -33,6 +33,7 @@ import textfieldStyles from '@adobe/spectrum-css-temp/components/textfield/vars.
3333
import {useComboBoxState} from '@react-stately/combobox';
3434
import {useFilter, useMessageFormatter} from '@react-aria/i18n';
3535
import {useHover} from '@react-aria/interactions';
36+
import {useLayoutEffect} from '@react-aria/utils';
3637
import {useProvider, useProviderProps} from '@react-spectrum/provider';
3738
import {useSearchAutocomplete} from '@react-aria/autocomplete';
3839

packages/@react-spectrum/searchwithin/src/SearchWithin.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
import {classNames, SlotProvider, useFocusableRef, useResizeObserver, useStyleProps} from '@react-spectrum/utils';
1414
import {Field} from '@react-spectrum/label';
1515
import {FocusableRef} from '@react-types/shared';
16-
import React, {useCallback, useLayoutEffect, useRef, useState} from 'react';
16+
import React, {useCallback, useRef, useState} from 'react';
1717
import {SpectrumSearchWithinProps} from '@react-types/searchwithin';
1818
import styles from '@adobe/spectrum-css-temp/components/searchwithin/vars.css';
1919
import {useLabel} from '@react-aria/label';
20+
import {useLayoutEffect} from '@react-aria/utils';
2021
import {useProvider, useProviderProps} from '@react-spectrum/provider';
2122

2223
function SearchWithin(props: SpectrumSearchWithinProps, ref: FocusableRef<HTMLElement>) {

0 commit comments

Comments
 (0)