mirror of
https://github.com/coder/coder.git
synced 2026-06-05 14:08:20 +00:00
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:
committed by
GitHub
parent
75870c22ab
commit
dbaafc863c
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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,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";
|
||||
|
||||
Reference in New Issue
Block a user