Skip to content

Commit dbaafc8

Browse files
authored
chore: update no-restricted-imports lint rule (coder#12180)
- prevent importing from the "monolith" lodash module. individual modules are better for tree shaking. - prevent importing `useTheme` and types from @mui/material/styles. prefer importing from @emotion/react.
1 parent 75870c2 commit dbaafc8

16 files changed

+88
-67
lines changed

site/.eslintrc.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ rules:
144144
"You should use the native HTML elements as span, p, h1, h2, h3..."
145145
- name: "@mui/material/Box"
146146
message: "You should use a <div> instead"
147+
- name: "@mui/material/styles"
148+
importNames: ["Interpolation", "Theme", "useTheme"]
149+
message: "Import from @emotion/react instead."
150+
- name: "lodash"
151+
message: "Import from lodash/<name> instead."
147152
no-unused-vars: "off"
148153
"object-curly-spacing": "off"
149154
react-hooks/exhaustive-deps: warn

site/src/components/FullPageLayout/Sidebar.tsx

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Interpolation, Theme, useTheme } from "@mui/material/styles";
2-
import { ComponentProps, HTMLAttributes } from "react";
3-
import { Link, LinkProps } from "react-router-dom";
1+
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
2+
import { type ComponentProps, type FC, type HTMLAttributes } from "react";
3+
import { Link, type LinkProps } from "react-router-dom";
44
import { TopbarIconButton } from "./Topbar";
55

6-
export const Sidebar = (props: HTMLAttributes<HTMLDivElement>) => {
6+
export const Sidebar: FC<HTMLAttributes<HTMLDivElement>> = (props) => {
77
const theme = useTheme();
88
return (
99
<div
@@ -23,14 +23,18 @@ export const Sidebar = (props: HTMLAttributes<HTMLDivElement>) => {
2323
);
2424
};
2525

26-
export const SidebarLink = (props: LinkProps) => {
26+
export const SidebarLink: FC<LinkProps> = (props) => {
2727
return <Link css={styles.sidebarItem} {...props} />;
2828
};
2929

30-
export const SidebarItem = (
31-
props: HTMLAttributes<HTMLButtonElement> & { isActive?: boolean },
32-
) => {
33-
const { isActive, ...buttonProps } = props;
30+
interface SidebarItemProps extends HTMLAttributes<HTMLButtonElement> {
31+
isActive?: boolean;
32+
}
33+
34+
export const SidebarItem: FC<SidebarItemProps> = ({
35+
isActive,
36+
...buttonProps
37+
}) => {
3438
const theme = useTheme();
3539

3640
return (
@@ -49,7 +53,7 @@ export const SidebarItem = (
4953
);
5054
};
5155

52-
export const SidebarCaption = (props: HTMLAttributes<HTMLSpanElement>) => {
56+
export const SidebarCaption: FC<HTMLAttributes<HTMLSpanElement>> = (props) => {
5357
return (
5458
<span
5559
css={{
@@ -66,29 +70,16 @@ export const SidebarCaption = (props: HTMLAttributes<HTMLSpanElement>) => {
6670
);
6771
};
6872

69-
export const SidebarIconButton = (
70-
props: { isActive: boolean } & ComponentProps<typeof TopbarIconButton>,
71-
) => {
72-
const theme = useTheme();
73+
interface SidebarIconButton extends ComponentProps<typeof TopbarIconButton> {
74+
isActive: boolean;
75+
}
7376

77+
export const SidebarIconButton: FC<SidebarIconButton> = (props) => {
7478
return (
7579
<TopbarIconButton
7680
css={[
7781
{ opacity: 0.75, "&:hover": { opacity: 1 } },
78-
props.isActive && {
79-
opacity: 1,
80-
position: "relative",
81-
"&::before": {
82-
content: '""',
83-
position: "absolute",
84-
left: 0,
85-
top: 0,
86-
bottom: 0,
87-
width: 2,
88-
backgroundColor: theme.palette.primary.main,
89-
height: "100%",
90-
},
91-
},
82+
props.isActive && styles.activeSidebarIconButton,
9283
]}
9384
{...props}
9485
/>
@@ -112,4 +103,19 @@ const styles = {
112103
backgroundColor: theme.palette.action.hover,
113104
},
114105
}),
106+
107+
activeSidebarIconButton: (theme) => ({
108+
opacity: 1,
109+
position: "relative",
110+
"&::before": {
111+
content: '""',
112+
position: "absolute",
113+
left: 0,
114+
top: 0,
115+
bottom: 0,
116+
width: 2,
117+
backgroundColor: theme.palette.primary.main,
118+
height: "100%",
119+
},
120+
}),
115121
} satisfies Record<string, Interpolation<Theme>>;

site/src/components/FullPageLayout/Topbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { css } from "@emotion/css";
22
import Button, { ButtonProps } from "@mui/material/Button";
33
import IconButton, { IconButtonProps } from "@mui/material/IconButton";
4-
import { useTheme } from "@mui/material/styles";
4+
import { useTheme } from "@emotion/react";
55
import { AvatarProps, ExternalAvatar } from "components/Avatar/Avatar";
66
import {
77
type FC,

site/src/components/Menu/Search.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import SearchOutlined from "@mui/icons-material/SearchOutlined";
22
// eslint-disable-next-line no-restricted-imports -- use it to have the component prop
3-
import Box, { BoxProps } from "@mui/material/Box";
4-
import { Interpolation, Theme, useTheme } from "@mui/material/styles";
3+
import Box, { type BoxProps } from "@mui/material/Box";
4+
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
55
import visuallyHidden from "@mui/utils/visuallyHidden";
6-
import { FC, HTMLAttributes, InputHTMLAttributes, forwardRef } from "react";
6+
import {
7+
type FC,
8+
type HTMLAttributes,
9+
type InputHTMLAttributes,
10+
forwardRef,
11+
} from "react";
712

813
export const Search = forwardRef<HTMLElement, BoxProps>(
914
({ children, ...boxProps }, ref) => {

site/src/hooks/usePaginatedQuery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect } from "react";
22
import { useEffectEvent } from "./hookPolyfills";
33
import { type SetURLSearchParams, useSearchParams } from "react-router-dom";
4-
import { clamp } from "lodash";
4+
import clamp from "lodash/clamp";
55

66
import {
77
type QueryFunctionContext,

site/src/pages/HealthPage/Content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { css } from "@emotion/css";
1414
import DoNotDisturbOnOutlined from "@mui/icons-material/DoNotDisturbOnOutlined";
1515
import { HealthMessage, HealthSeverity } from "api/typesGenerated";
1616
import Link from "@mui/material/Link";
17-
import { useTheme } from "@mui/material/styles";
17+
import { useTheme } from "@emotion/react";
1818

1919
const CONTENT_PADDING = 36;
2020

site/src/pages/HealthPage/DERPPage.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
import { Link, useOutletContext } from "react-router-dom";
2+
import type {
3+
HealthMessage,
4+
HealthSeverity,
5+
HealthcheckReport,
6+
} from "api/typesGenerated";
7+
import Button from "@mui/material/Button";
8+
import LocationOnOutlined from "@mui/icons-material/LocationOnOutlined";
9+
import { Alert } from "components/Alert/Alert";
10+
import { Helmet } from "react-helmet-async";
11+
import { pageTitle } from "utils/page";
12+
import { useTheme } from "@emotion/react";
13+
import { type FC } from "react";
214
import {
315
Header,
416
HeaderTitle,
@@ -9,19 +21,8 @@ import {
921
Logs,
1022
HealthyDot,
1123
} from "./Content";
12-
import {
13-
HealthMessage,
14-
HealthSeverity,
15-
HealthcheckReport,
16-
} from "api/typesGenerated";
17-
import Button from "@mui/material/Button";
18-
import LocationOnOutlined from "@mui/icons-material/LocationOnOutlined";
19-
import { healthyColor } from "./healthyColor";
20-
import { Alert } from "components/Alert/Alert";
21-
import { Helmet } from "react-helmet-async";
22-
import { pageTitle } from "utils/page";
23-
import { useTheme } from "@mui/material/styles";
2424
import { DismissWarningButton } from "./DismissWarningButton";
25+
import { healthyColor } from "./healthyColor";
2526

2627
const flags = [
2728
"UDP",
@@ -38,7 +39,7 @@ const flags = [
3839
"PCP",
3940
];
4041

41-
export const DERPPage = () => {
42+
export const DERPPage: FC = () => {
4243
const { derp } = useOutletContext<HealthcheckReport>();
4344
const { netcheck, regions, netcheck_logs: logs } = derp;
4445
const theme = useTheme();

site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,22 @@ import {
99
} from "./Content";
1010
import { Helmet } from "react-helmet-async";
1111
import { pageTitle } from "utils/page";
12-
import { useTheme } from "@mui/material/styles";
12+
import { useTheme } from "@emotion/react";
1313
import { DismissWarningButton } from "./DismissWarningButton";
1414
import { Alert } from "components/Alert/Alert";
15-
import { HealthcheckReport } from "api/typesGenerated";
15+
import type { HealthcheckReport } from "api/typesGenerated";
1616
import { createDayString } from "utils/createDayString";
17-
17+
import { type FC } from "react";
1818
import { useOutletContext } from "react-router-dom";
1919
import Business from "@mui/icons-material/Business";
2020
import Person from "@mui/icons-material/Person";
2121
import SwapHoriz from "@mui/icons-material/SwapHoriz";
2222
import Tooltip from "@mui/material/Tooltip";
2323
import Sell from "@mui/icons-material/Sell";
24-
import { FC } from "react";
2524
import CloseIcon from "@mui/icons-material/Close";
2625
import IconButton from "@mui/material/IconButton";
2726

28-
export const ProvisionerDaemonsPage = () => {
27+
export const ProvisionerDaemonsPage: FC = () => {
2928
const healthStatus = useOutletContext<HealthcheckReport>();
3029
const { provisioner_daemons: daemons } = healthStatus;
3130
const theme = useTheme();

site/src/pages/HealthPage/WebsocketPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { HealthcheckReport } from "api/typesGenerated";
1111
import CodeOutlined from "@mui/icons-material/CodeOutlined";
1212
import Tooltip from "@mui/material/Tooltip";
13-
import { useTheme } from "@mui/material/styles";
13+
import { useTheme } from "@emotion/react";
1414
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
1515
import { Alert } from "components/Alert/Alert";
1616
import { pageTitle } from "utils/page";

site/src/pages/HealthPage/WorkspaceProxyPage.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ import {
88
Main,
99
Pill,
1010
} from "./Content";
11-
import { HealthcheckReport } from "api/typesGenerated";
12-
import { useTheme } from "@mui/material/styles";
11+
import type { HealthcheckReport } from "api/typesGenerated";
12+
import { useTheme } from "@emotion/react";
1313
import { createDayString } from "utils/createDayString";
1414
import PublicOutlined from "@mui/icons-material/PublicOutlined";
1515
import Tooltip from "@mui/material/Tooltip";
1616
import TagOutlined from "@mui/icons-material/TagOutlined";
1717
import { Alert } from "components/Alert/Alert";
18+
import { type FC } from "react";
1819
import { Helmet } from "react-helmet-async";
1920
import { pageTitle } from "utils/page";
2021
import { DismissWarningButton } from "./DismissWarningButton";
2122

22-
export const WorkspaceProxyPage = () => {
23+
export const WorkspaceProxyPage: FC = () => {
2324
const healthStatus = useOutletContext<HealthcheckReport>();
2425
const { workspace_proxy } = healthStatus;
2526
const { regions } = workspace_proxy.workspace_proxies;

site/src/pages/HealthPage/healthyColor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Theme } from "@mui/material/styles";
2-
import { HealthSeverity } from "api/typesGenerated";
1+
import type { Theme } from "@emotion/react";
2+
import type { HealthSeverity } from "api/typesGenerated";
33

44
export const healthyColor = (theme: Theme, severity: HealthSeverity) => {
55
switch (severity) {

site/src/pages/WorkspacePage/ResourcesSidebar.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Interpolation, Theme } from "@emotion/react";
1+
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
22
import Skeleton from "@mui/material/Skeleton";
3-
import { useTheme } from "@mui/material/styles";
4-
import { WorkspaceResource } from "api/typesGenerated";
3+
import { type FC } from "react";
4+
import type { WorkspaceResource } from "api/typesGenerated";
55
import {
66
Sidebar,
77
SidebarCaption,
@@ -16,9 +16,13 @@ type ResourcesSidebarProps = {
1616
isSelected: (resource: WorkspaceResource) => boolean;
1717
};
1818

19-
export const ResourcesSidebar = (props: ResourcesSidebarProps) => {
19+
export const ResourcesSidebar: FC<ResourcesSidebarProps> = ({
20+
failed,
21+
onChange,
22+
isSelected,
23+
resources,
24+
}) => {
2025
const theme = useTheme();
21-
const { failed, onChange, isSelected, resources } = props;
2226

2327
return (
2428
<Sidebar>
@@ -83,7 +87,7 @@ export const ResourcesSidebar = (props: ResourcesSidebarProps) => {
8387
);
8488
};
8589

86-
export const ResourceSidebarItemSkeleton = () => {
90+
export const ResourceSidebarItemSkeleton: FC = () => {
8791
return (
8892
<div css={[styles.root, { pointerEvents: "none" }]}>
8993
<Skeleton variant="circular" width={16} height={16} />

site/src/pages/WorkspacePage/ResourcesSidebarContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useTheme } from "@mui/material/styles";
1+
import { useTheme } from "@emotion/react";
22
import { Workspace } from "api/typesGenerated";
33
import { SidebarLink, SidebarCaption } from "components/FullPageLayout/Sidebar";
44

site/src/pages/WorkspacePage/Workspace.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { WorkspaceDeletedBanner } from "./WorkspaceDeletedBanner";
1515
import { WorkspaceTopbar } from "./WorkspaceTopbar";
1616
import { HistorySidebar } from "./HistorySidebar";
1717
import HistoryOutlined from "@mui/icons-material/HistoryOutlined";
18-
import { useTheme } from "@mui/material/styles";
18+
import { useTheme } from "@emotion/react";
1919
import { SidebarIconButton } from "components/FullPageLayout/Sidebar";
2020
import HubOutlined from "@mui/icons-material/HubOutlined";
2121
import { ResourcesSidebar } from "./ResourcesSidebar";

site/src/pages/WorkspacePage/WorkspaceScheduleControls.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import IconButton from "@mui/material/IconButton";
1616
import RemoveIcon from "@mui/icons-material/RemoveOutlined";
1717
import AddIcon from "@mui/icons-material/AddOutlined";
1818
import Tooltip from "@mui/material/Tooltip";
19-
import _ from "lodash";
2019
import { getErrorMessage } from "api/errors";
2120
import {
2221
updateDeadline,

site/src/theme/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// eslint-disable-next-line no-restricted-imports -- we still use `Theme` as a basis for our actual theme, for now.
12
import type { Theme as MuiTheme } from "@mui/material/styles";
23
import type * as monaco from "monaco-editor";
34
import type { NewTheme } from "./experimental";

0 commit comments

Comments
 (0)