Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: make react-hooks/exhaustive-deps eslint rule error vs. warn #950

Merged
merged 7 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 39 additions & 19 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: 2.1

orbs:
node: circleci/node@5.0.0
node: circleci/node@5.1.0

node-image: &node-image
image: cimg/node:18.13.0
Expand All @@ -18,6 +18,10 @@ workflows:
- npm-readonly
- github
- dockerhub
- validate-code:
context:
- npm-readonly
- dockerhub
- publish:
context:
- npm-publish
Expand All @@ -34,32 +38,53 @@ workflows:
- npm-readonly
- dockerhub

jobs:
build:
resource_class: "xlarge"
docker:
- <<: *node-image
commands:
bootstrap:
steps:
- checkout
- run:
name: Login in NPM
command: 'echo "npmAuthToken: $NPM_TOKEN" >> ${HOME}/.yarnrc.yml'
- node/install-packages:
pkg-manager: yarn
pkg-manager: yarn-berry
include-branch-in-cache-key: false

jobs:
build:
resource_class: "xlarge"
docker:
- <<: *node-image
steps:
- bootstrap
- run: yarn build
- run: yarn test

validate-code:
docker:
- <<: *node-image
steps:
- bootstrap
- restore_cache:
name: Restore ESLint Cache
keys:
- eslint-cache-{{ .Branch }}
# If this branch doesn't have a warm cache yet, fall back to main to try to speed up the initial build
- eslint-cache-main
- run:
name: Run ESLint
command: yarn lint --cache --cache-location .eslintcache --quiet
- save_cache:
name: Save ESLint Cache
key: eslint-cache-{{ .Branch }}
paths:
- .eslintcache

publish:
resource_class: "xlarge"
docker:
- <<: *node-image
steps:
- checkout
- run:
name: Login in NPM
command: 'echo "npmAuthToken: $NPM_TOKEN" >> ${HOME}/.yarnrc.yml'
- node/install-packages:
pkg-manager: yarn
- bootstrap
- run: yarn semantic-release

chromatic:
Expand All @@ -72,12 +97,7 @@ jobs:
- <<: *node-image
working_directory: ~/project
steps:
- checkout
- run:
name: Login in NPM
command: 'echo "npmAuthToken: $NPM_TOKEN" >> ${HOME}/.yarnrc.yml'
- node/install-packages:
pkg-manager: yarn
- bootstrap
- when:
condition:
equal: [main, <<pipeline.git.branch>>]
Expand Down
807 changes: 0 additions & 807 deletions .yarn/releases/yarn-3.3.0.cjs

This file was deleted.

874 changes: 874 additions & 0 deletions .yarn/releases/yarn-3.6.3.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-3.3.0.cjs
yarnPath: .yarn/releases/yarn-3.6.3.cjs
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"@emotion/babel-preset-css-prop": "^11.10.0",
"@emotion/jest": "^11.10.5",
"@emotion/react": "^11.10.6",
"@homebound/eslint-config": "1.6.1",
"@homebound/eslint-config": "^1.8.0",
"@homebound/rtl-react-router-utils": "1.0.3",
"@homebound/rtl-utils": "^2.65.0",
"@homebound/truss": "^1.131.0",
Expand Down Expand Up @@ -139,5 +139,5 @@
"@types/react": "18.0.28",
"react-router": "5.3.4"
},
"packageManager": "yarn@3.3.0"
"packageManager": "yarn@3.6.3"
}
21 changes: 13 additions & 8 deletions src/components/AutoSaveIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ interface AutoSaveIndicatorProps {
export function AutoSaveIndicator({ hideOnIdle, doNotReset }: AutoSaveIndicatorProps) {
const { status, resetStatus, errors } = useAutoSaveStatus();

useEffect(() => {
if (doNotReset) return;
/**
* Any time AutoSaveIndicator dismounts, most likely on Page Navigation,
* state should clear before the next Indicator mounts
*/
return () => resetStatus();
}, []);
useEffect(
() => {
if (doNotReset) return;
/**
* Any time AutoSaveIndicator dismounts, most likely on Page Navigation,
* state should clear before the next Indicator mounts
*/
return () => resetStatus();
},
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
);

switch (status) {
case AutoSaveStatus.IDLE:
Expand Down
40 changes: 24 additions & 16 deletions src/components/BeamContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,26 @@ export function BeamProvider({ children, ...presentationProps }: BeamProviderPro

// We essentially expose the refs, but with our own getters/setters so that we can
// have the setters call `tick` to re-render this Provider
const context = useMemo<BeamContextState>(() => {
return {
// These two keys need to trigger re-renders on change
modalState: new PretendRefThatTicks(modalRef, tick),
drawerContentStack: new PretendRefThatTicks(drawerContentStackRef, tick),
// The rest we don't need to re-render when these are mutated, so just expose as-is
modalCanCloseChecks: modalCanCloseChecksRef,
modalHeaderDiv,
modalBodyDiv,
modalFooterDiv,
drawerCanCloseChecks,
drawerCanCloseDetailsChecks,
sdHeaderDiv,
};
}, [modalBodyDiv, modalFooterDiv]);
const context = useMemo<BeamContextState>(
() => {
return {
// These two keys need to trigger re-renders on change
modalState: new PretendRefThatTicks(modalRef, tick),
drawerContentStack: new PretendRefThatTicks(drawerContentStackRef, tick),
// The rest we don't need to re-render when these are mutated, so just expose as-is
modalCanCloseChecks: modalCanCloseChecksRef,
modalHeaderDiv,
modalBodyDiv,
modalFooterDiv,
drawerCanCloseChecks,
drawerCanCloseDetailsChecks,
sdHeaderDiv,
};
},
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
[modalBodyDiv, modalFooterDiv],
);

return (
<BeamContext.Provider value={{ ...context }}>
Expand All @@ -109,7 +114,10 @@ export function BeamProvider({ children, ...presentationProps }: BeamProviderPro

/** Looks like a ref, but invokes a re-render on set (w/o changing the setter identity). */
class PretendRefThatTicks<T> implements MutableRefObject<T> {
constructor(private ref: MutableRefObject<T>, private tick: () => void) {}
constructor(
private ref: MutableRefObject<T>,
private tick: () => void,
) {}
get current(): T {
return this.ref.current;
}
Expand Down
29 changes: 25 additions & 4 deletions src/components/CssReset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,16 @@ Improve consistency of default fonts in all browsers. (https://github.com/sindre
*/

body {
font-family: system-ui, -apple-system, /* Firefox supports this but not yet system-ui */ "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
font-family:
system-ui,
-apple-system,
/* Firefox supports this but not yet system-ui */ "Segoe UI",
Roboto,
Helvetica,
Arial,
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji";
}

/*
Expand Down Expand Up @@ -376,8 +384,21 @@ const tailwindPreflightReset = css`
* to override it to ensure consistency even when using the default theme.
*/
html {
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
font-family:
Inter,
ui-sans-serif,
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
"Noto Sans",
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji"; /* 1 */
line-height: 1.5; /* 2 */
}
Expand Down
37 changes: 21 additions & 16 deletions src/components/DnDGrid/useDnDGridItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,30 @@ export function useDnDGridItem(props: useDnDGridItemProps) {
const { id, itemRef } = props;
const { dragEl, onDragHandleKeyDown } = useDnDGridContext();

const { dragItemProps, dragHandleProps } = useMemo(() => {
function initDraggable() {
if (itemRef.current) {
dragEl.current = itemRef.current;
const { dragItemProps, dragHandleProps } = useMemo(
() => {
function initDraggable() {
if (itemRef.current) {
dragEl.current = itemRef.current;
}
}
}

return {
dragItemProps: { [gridItemIdKey]: id },
dragHandleProps: {
onMouseDown: initDraggable,
onTouchStart: initDraggable,
onKeyDown: (e: KeyboardEvent) => {
initDraggable();
onDragHandleKeyDown(e);
return {
dragItemProps: { [gridItemIdKey]: id },
dragHandleProps: {
onMouseDown: initDraggable,
onTouchStart: initDraggable,
onKeyDown: (e: KeyboardEvent) => {
initDraggable();
onDragHandleKeyDown(e);
},
},
},
};
}, [dragEl, id, itemRef]);
};
},
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
[dragEl, id, itemRef],
);

return { dragHandleProps, dragItemProps };
}
Expand Down
5 changes: 4 additions & 1 deletion src/components/Filters/BaseFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { TestIds } from "src/utils/useTestIds";
* detail.
*/
export class BaseFilter<V, P extends { label?: string; defaultValue?: V }> {
constructor(protected key: string, protected props: P) {}
constructor(
protected key: string,
protected props: P,
) {}

get label(): string {
return this.props.label || defaultLabel(this.key);
Expand Down
2 changes: 2 additions & 0 deletions src/components/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export function IconButton(props: IconButtonProps) {
...(isFocusVisible || forceFocusStyles ? iconButtonStylesFocus : {}),
...(isDisabled && iconButtonStylesDisabled),
}),
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
[isHovered, isFocusVisible, isDisabled, compact],
);
const iconColor = contrast ? contrastIconColor : defaultIconColor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ function TableExample({ numCols = 10, numRows = 100 }: { numCols?: number; numRo
w: "200px",
sticky: i === 0 ? "left" : undefined,
})),
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
[numCols],
);

Expand Down
6 changes: 6 additions & 0 deletions src/components/Modal/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export const ButtonsInFooter = () => {
),
});
// Immediately open the modal for Chromatic snapshots
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(open, [openModal]);
return <Button label="Open" onClick={open} />;
};
Expand Down Expand Up @@ -132,6 +134,8 @@ function ModalExample(props: ModalExampleProps) {
drawHeaderBorder,
});
// Immediately open the modal for Chromatic snapshots
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(open, [openModal]);
return <Button label="Open" onClick={open} />;
}
Expand All @@ -146,6 +150,8 @@ function ModalFilterTableExample({ size, forceScrolling }: Pick<ModalProps, "siz

// Immediately open the modal for Chromatic snapshots
const open = () => openModal(modalProps);
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(open, [openModal]);

return <Button label="Open" onClick={open} />;
Expand Down
2 changes: 2 additions & 0 deletions src/components/Modal/Modal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ describe("Modal", () => {

function TestModalApp(props: ModalProps & { canClose?: () => boolean }) {
const { openModal, addCanClose } = useModal();
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => openModal(props), [openModal]);
if (props.canClose) {
addCanClose(props.canClose);
Expand Down
Loading