chore: update no-restricted-imports lint rule (#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.
This commit is contained in:
Kayla Washburn-Love
2024-02-16 09:54:40 -07:00
committed by GitHub
parent 75870c22ab
commit dbaafc863c
16 changed files with 88 additions and 67 deletions
+5
View File
@@ -144,6 +144,11 @@ rules:
"You should use the native HTML elements as span, p, h1, h2, h3..."
- name: "@mui/material/Box"
message: "You should use a <div> instead"
- name: "@mui/material/styles"
importNames: ["Interpolation", "Theme", "useTheme"]
message: "Import from @emotion/react instead."
- name: "lodash"
message: "Import from lodash/<name> instead."
no-unused-vars: "off"
"object-curly-spacing": "off"
react-hooks/exhaustive-deps: warn
+34 -28
View File
@@ -1,9 +1,9 @@
import { Interpolation, Theme, useTheme } from "@mui/material/styles";
import { ComponentProps, HTMLAttributes } from "react";
import { Link, LinkProps } from "react-router-dom";
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
import { type ComponentProps, type FC, type HTMLAttributes } from "react";
import { Link, type LinkProps } from "react-router-dom";
import { TopbarIconButton } from "./Topbar";
export const Sidebar = (props: HTMLAttributes<HTMLDivElement>) => {
export const Sidebar: FC<HTMLAttributes<HTMLDivElement>> = (props) => {
const theme = useTheme();
return (
<div
@@ -23,14 +23,18 @@ export const Sidebar = (props: HTMLAttributes<HTMLDivElement>) => {
);
};
export const SidebarLink = (props: LinkProps) => {
export const SidebarLink: FC<LinkProps> = (props) => {
return <Link css={styles.sidebarItem} {...props} />;
};
export const SidebarItem = (
props: HTMLAttributes<HTMLButtonElement> & { isActive?: boolean },
) => {
const { isActive, ...buttonProps } = props;
interface SidebarItemProps extends HTMLAttributes<HTMLButtonElement> {
isActive?: boolean;
}
export const SidebarItem: FC<SidebarItemProps> = ({
isActive,
...buttonProps
}) => {
const theme = useTheme();
return (
@@ -49,7 +53,7 @@ export const SidebarItem = (
);
};
export const SidebarCaption = (props: HTMLAttributes<HTMLSpanElement>) => {
export const SidebarCaption: FC<HTMLAttributes<HTMLSpanElement>> = (props) => {
return (
<span
css={{
@@ -66,29 +70,16 @@ export const SidebarCaption = (props: HTMLAttributes<HTMLSpanElement>) => {
);
};
export const SidebarIconButton = (
props: { isActive: boolean } & ComponentProps<typeof TopbarIconButton>,
) => {
const theme = useTheme();
interface SidebarIconButton extends ComponentProps<typeof TopbarIconButton> {
isActive: boolean;
}
export const SidebarIconButton: FC<SidebarIconButton> = (props) => {
return (
<TopbarIconButton
css={[
{ opacity: 0.75, "&:hover": { opacity: 1 } },
props.isActive && {
opacity: 1,
position: "relative",
"&::before": {
content: '""',
position: "absolute",
left: 0,
top: 0,
bottom: 0,
width: 2,
backgroundColor: theme.palette.primary.main,
height: "100%",
},
},
props.isActive && styles.activeSidebarIconButton,
]}
{...props}
/>
@@ -112,4 +103,19 @@ const styles = {
backgroundColor: theme.palette.action.hover,
},
}),
activeSidebarIconButton: (theme) => ({
opacity: 1,
position: "relative",
"&::before": {
content: '""',
position: "absolute",
left: 0,
top: 0,
bottom: 0,
width: 2,
backgroundColor: theme.palette.primary.main,
height: "100%",
},
}),
} satisfies Record<string, Interpolation<Theme>>;
@@ -1,7 +1,7 @@
import { css } from "@emotion/css";
import Button, { ButtonProps } from "@mui/material/Button";
import IconButton, { IconButtonProps } from "@mui/material/IconButton";
import { useTheme } from "@mui/material/styles";
import { useTheme } from "@emotion/react";
import { AvatarProps, ExternalAvatar } from "components/Avatar/Avatar";
import {
type FC,
+8 -3
View File
@@ -1,9 +1,14 @@
import SearchOutlined from "@mui/icons-material/SearchOutlined";
// eslint-disable-next-line no-restricted-imports -- use it to have the component prop
import Box, { BoxProps } from "@mui/material/Box";
import { Interpolation, Theme, useTheme } from "@mui/material/styles";
import Box, { type BoxProps } from "@mui/material/Box";
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
import visuallyHidden from "@mui/utils/visuallyHidden";
import { FC, HTMLAttributes, InputHTMLAttributes, forwardRef } from "react";
import {
type FC,
type HTMLAttributes,
type InputHTMLAttributes,
forwardRef,
} from "react";
export const Search = forwardRef<HTMLElement, BoxProps>(
({ children, ...boxProps }, ref) => {
+1 -1
View File
@@ -1,7 +1,7 @@
import { useEffect } from "react";
import { useEffectEvent } from "./hookPolyfills";
import { type SetURLSearchParams, useSearchParams } from "react-router-dom";
import { clamp } from "lodash";
import clamp from "lodash/clamp";
import {
type QueryFunctionContext,
+1 -1
View File
@@ -14,7 +14,7 @@ import { css } from "@emotion/css";
import DoNotDisturbOnOutlined from "@mui/icons-material/DoNotDisturbOnOutlined";
import { HealthMessage, HealthSeverity } from "api/typesGenerated";
import Link from "@mui/material/Link";
import { useTheme } from "@mui/material/styles";
import { useTheme } from "@emotion/react";
const CONTENT_PADDING = 36;
+14 -13
View File
@@ -1,4 +1,16 @@
import { Link, useOutletContext } from "react-router-dom";
import type {
HealthMessage,
HealthSeverity,
HealthcheckReport,
} from "api/typesGenerated";
import Button from "@mui/material/Button";
import LocationOnOutlined from "@mui/icons-material/LocationOnOutlined";
import { Alert } from "components/Alert/Alert";
import { Helmet } from "react-helmet-async";
import { pageTitle } from "utils/page";
import { useTheme } from "@emotion/react";
import { type FC } from "react";
import {
Header,
HeaderTitle,
@@ -9,19 +21,8 @@ import {
Logs,
HealthyDot,
} from "./Content";
import {
HealthMessage,
HealthSeverity,
HealthcheckReport,
} from "api/typesGenerated";
import Button from "@mui/material/Button";
import LocationOnOutlined from "@mui/icons-material/LocationOnOutlined";
import { healthyColor } from "./healthyColor";
import { Alert } from "components/Alert/Alert";
import { Helmet } from "react-helmet-async";
import { pageTitle } from "utils/page";
import { useTheme } from "@mui/material/styles";
import { DismissWarningButton } from "./DismissWarningButton";
import { healthyColor } from "./healthyColor";
const flags = [
"UDP",
@@ -38,7 +39,7 @@ const flags = [
"PCP",
];
export const DERPPage = () => {
export const DERPPage: FC = () => {
const { derp } = useOutletContext<HealthcheckReport>();
const { netcheck, regions, netcheck_logs: logs } = derp;
const theme = useTheme();
@@ -9,23 +9,22 @@ import {
} from "./Content";
import { Helmet } from "react-helmet-async";
import { pageTitle } from "utils/page";
import { useTheme } from "@mui/material/styles";
import { useTheme } from "@emotion/react";
import { DismissWarningButton } from "./DismissWarningButton";
import { Alert } from "components/Alert/Alert";
import { HealthcheckReport } from "api/typesGenerated";
import type { HealthcheckReport } from "api/typesGenerated";
import { createDayString } from "utils/createDayString";
import { type FC } from "react";
import { useOutletContext } from "react-router-dom";
import Business from "@mui/icons-material/Business";
import Person from "@mui/icons-material/Person";
import SwapHoriz from "@mui/icons-material/SwapHoriz";
import Tooltip from "@mui/material/Tooltip";
import Sell from "@mui/icons-material/Sell";
import { FC } from "react";
import CloseIcon from "@mui/icons-material/Close";
import IconButton from "@mui/material/IconButton";
export const ProvisionerDaemonsPage = () => {
export const ProvisionerDaemonsPage: FC = () => {
const healthStatus = useOutletContext<HealthcheckReport>();
const { provisioner_daemons: daemons } = healthStatus;
const theme = useTheme();
+1 -1
View File
@@ -10,7 +10,7 @@ import {
import { HealthcheckReport } from "api/typesGenerated";
import CodeOutlined from "@mui/icons-material/CodeOutlined";
import Tooltip from "@mui/material/Tooltip";
import { useTheme } from "@mui/material/styles";
import { useTheme } from "@emotion/react";
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
import { Alert } from "components/Alert/Alert";
import { pageTitle } from "utils/page";
@@ -8,18 +8,19 @@ import {
Main,
Pill,
} from "./Content";
import { HealthcheckReport } from "api/typesGenerated";
import { useTheme } from "@mui/material/styles";
import type { HealthcheckReport } from "api/typesGenerated";
import { useTheme } from "@emotion/react";
import { createDayString } from "utils/createDayString";
import PublicOutlined from "@mui/icons-material/PublicOutlined";
import Tooltip from "@mui/material/Tooltip";
import TagOutlined from "@mui/icons-material/TagOutlined";
import { Alert } from "components/Alert/Alert";
import { type FC } from "react";
import { Helmet } from "react-helmet-async";
import { pageTitle } from "utils/page";
import { DismissWarningButton } from "./DismissWarningButton";
export const WorkspaceProxyPage = () => {
export const WorkspaceProxyPage: FC = () => {
const healthStatus = useOutletContext<HealthcheckReport>();
const { workspace_proxy } = healthStatus;
const { regions } = workspace_proxy.workspace_proxies;
+2 -2
View File
@@ -1,5 +1,5 @@
import { Theme } from "@mui/material/styles";
import { HealthSeverity } from "api/typesGenerated";
import type { Theme } from "@emotion/react";
import type { HealthSeverity } from "api/typesGenerated";
export const healthyColor = (theme: Theme, severity: HealthSeverity) => {
switch (severity) {
@@ -1,7 +1,7 @@
import { Interpolation, Theme } from "@emotion/react";
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
import Skeleton from "@mui/material/Skeleton";
import { useTheme } from "@mui/material/styles";
import { WorkspaceResource } from "api/typesGenerated";
import { type FC } from "react";
import type { WorkspaceResource } from "api/typesGenerated";
import {
Sidebar,
SidebarCaption,
@@ -16,9 +16,13 @@ type ResourcesSidebarProps = {
isSelected: (resource: WorkspaceResource) => boolean;
};
export const ResourcesSidebar = (props: ResourcesSidebarProps) => {
export const ResourcesSidebar: FC<ResourcesSidebarProps> = ({
failed,
onChange,
isSelected,
resources,
}) => {
const theme = useTheme();
const { failed, onChange, isSelected, resources } = props;
return (
<Sidebar>
@@ -83,7 +87,7 @@ export const ResourcesSidebar = (props: ResourcesSidebarProps) => {
);
};
export const ResourceSidebarItemSkeleton = () => {
export const ResourceSidebarItemSkeleton: FC = () => {
return (
<div css={[styles.root, { pointerEvents: "none" }]}>
<Skeleton variant="circular" width={16} height={16} />
@@ -1,4 +1,4 @@
import { useTheme } from "@mui/material/styles";
import { useTheme } from "@emotion/react";
import { Workspace } from "api/typesGenerated";
import { SidebarLink, SidebarCaption } from "components/FullPageLayout/Sidebar";
+1 -1
View File
@@ -15,7 +15,7 @@ import { WorkspaceDeletedBanner } from "./WorkspaceDeletedBanner";
import { WorkspaceTopbar } from "./WorkspaceTopbar";
import { HistorySidebar } from "./HistorySidebar";
import HistoryOutlined from "@mui/icons-material/HistoryOutlined";
import { useTheme } from "@mui/material/styles";
import { useTheme } from "@emotion/react";
import { SidebarIconButton } from "components/FullPageLayout/Sidebar";
import HubOutlined from "@mui/icons-material/HubOutlined";
import { ResourcesSidebar } from "./ResourcesSidebar";
@@ -16,7 +16,6 @@ import IconButton from "@mui/material/IconButton";
import RemoveIcon from "@mui/icons-material/RemoveOutlined";
import AddIcon from "@mui/icons-material/AddOutlined";
import Tooltip from "@mui/material/Tooltip";
import _ from "lodash";
import { getErrorMessage } from "api/errors";
import {
updateDeadline,
+1
View File
@@ -1,3 +1,4 @@
// eslint-disable-next-line no-restricted-imports -- we still use `Theme` as a basis for our actual theme, for now.
import type { Theme as MuiTheme } from "@mui/material/styles";
import type * as monaco from "monaco-editor";
import type { NewTheme } from "./experimental";