diff --git a/site/src/components/Tabs/Tabs.tsx b/site/src/components/Tabs/Tabs.tsx new file mode 100644 index 0000000000000..b7e6c6de61eb7 --- /dev/null +++ b/site/src/components/Tabs/Tabs.tsx @@ -0,0 +1,71 @@ +import { ReactNode } from "react"; +import { NavLink, NavLinkProps } from "react-router-dom"; +import { combineClasses } from "utils/combineClasses"; +import { Margins } from "components/Margins/Margins"; +import { css } from "@emotion/css"; +import { useTheme } from "@mui/material/styles"; + +export const Tabs = ({ children }: { children: ReactNode }) => { + return ( +
({ + borderBottom: `1px solid ${theme.palette.divider}`, + marginBottom: theme.spacing(5), + })} + > + ({ + display: "flex", + alignItems: "center", + gap: theme.spacing(0.25), + })} + > + {children} + +
+ ); +}; + +export const TabLink = (props: NavLinkProps) => { + const theme = useTheme(); + + const baseTabLink = css` + text-decoration: none; + color: ${theme.palette.text.secondary}; + font-size: 14px; + display: block; + padding: ${theme.spacing(0, 2, 2)}; + + &:hover { + color: ${theme.palette.text.primary}; + } + `; + + const activeTabLink = css` + color: ${theme.palette.text.primary}; + position: relative; + + &:before { + content: ""; + left: 0; + bottom: 0; + height: 2px; + width: 100%; + background: ${theme.palette.secondary.dark}; + position: absolute; + } + `; + + return ( + + combineClasses([ + baseTabLink, + isActive ? activeTabLink : undefined, + props.className as string, + ]) + } + {...props} + /> + ); +}; diff --git a/site/src/components/UsersLayout/UsersLayout.tsx b/site/src/components/UsersLayout/UsersLayout.tsx index 7a4d380b3e8cd..397cadc25bb60 100644 --- a/site/src/components/UsersLayout/UsersLayout.tsx +++ b/site/src/components/UsersLayout/UsersLayout.tsx @@ -1,6 +1,5 @@ import Button from "@mui/material/Button"; import Link from "@mui/material/Link"; -import { makeStyles } from "@mui/styles"; import GroupAdd from "@mui/icons-material/GroupAddOutlined"; import PersonAdd from "@mui/icons-material/PersonAddOutlined"; import { USERS_LINK } from "components/Dashboard/Navbar/NavbarView"; @@ -8,18 +7,11 @@ import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"; import { useFeatureVisibility } from "hooks/useFeatureVisibility"; import { usePermissions } from "hooks/usePermissions"; import { FC } from "react"; -import { - Link as RouterLink, - NavLink, - Outlet, - useNavigate, -} from "react-router-dom"; -import { combineClasses } from "utils/combineClasses"; +import { Link as RouterLink, Outlet, useNavigate } from "react-router-dom"; import { Margins } from "components/Margins/Margins"; -import { Stack } from "components/Stack/Stack"; +import { TabLink, Tabs } from "components/Tabs/Tabs"; export const UsersLayout: FC = () => { - const styles = useStyles(); const { createUser: canCreateUser, createGroup: canCreateGroup } = usePermissions(); const navigate = useNavigate(); @@ -53,35 +45,10 @@ export const UsersLayout: FC = () => { -
- - - - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) - } - > - Users - - - combineClasses([ - styles.tabItem, - isActive ? styles.tabItemActive : undefined, - ]) - } - > - Groups - - - -
+ + Users + Groups + @@ -89,39 +56,3 @@ export const UsersLayout: FC = () => { ); }; - -export const useStyles = makeStyles((theme) => { - return { - tabs: { - borderBottom: `1px solid ${theme.palette.divider}`, - marginBottom: theme.spacing(5), - }, - - tabItem: { - textDecoration: "none", - color: theme.palette.text.secondary, - fontSize: 14, - display: "block", - padding: theme.spacing(0, 2, 2), - - "&:hover": { - color: theme.palette.text.primary, - }, - }, - - tabItemActive: { - color: theme.palette.text.primary, - position: "relative", - - "&:before": { - content: `""`, - left: 0, - bottom: 0, - height: 2, - width: "100%", - background: theme.palette.secondary.dark, - position: "absolute", - }, - }, - }; -}); diff --git a/site/src/pages/TemplatePage/TemplateLayout.tsx b/site/src/pages/TemplatePage/TemplateLayout.tsx index 24f4487048320..41a15264c9a7b 100644 --- a/site/src/pages/TemplatePage/TemplateLayout.tsx +++ b/site/src/pages/TemplatePage/TemplateLayout.tsx @@ -1,8 +1,7 @@ -import { css } from "@emotion/css"; import { useTheme } from "@emotion/react"; import { createContext, type FC, Suspense, useContext } from "react"; import { useQuery } from "react-query"; -import { NavLink, Outlet, useNavigate, useParams } from "react-router-dom"; +import { Outlet, useNavigate, useParams } from "react-router-dom"; import type { AuthorizationRequest } from "api/typesGenerated"; import { checkAuthorization, @@ -11,10 +10,10 @@ import { } from "api/api"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Margins } from "components/Margins/Margins"; -import { Stack } from "components/Stack/Stack"; import { Loader } from "components/Loader/Loader"; import { useOrganizationId } from "hooks/useOrganizationId"; import { TemplatePageHeader } from "./TemplatePageHeader"; +import { TabLink, Tabs } from "components/Tabs/Tabs"; const templatePermissions = ( templateId: string, @@ -85,34 +84,6 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({ return ; } - const itemStyles = css` - text-decoration: none; - color: ${theme.palette.text.secondary}; - font-size: 14; - display: block; - padding: ${theme.spacing(0, 2, 2)}; - - &:hover { - color: ${theme.palette.text.primary}; - } - `; - - const activeItemStyles = css` - ${itemStyles} - color: ${theme.palette.text.primary}; - position: relative; - - &:before { - content: ""; - left: 0; - bottom: 0; - height: 2; - width: 100%; - background: ${theme.palette.secondary.dark}; - position: absolute; - } - `; - return ( <> = ({ }} /> -
- - - - isActive ? activeItemStyles : itemStyles - } - > - Summary - - - isActive ? activeItemStyles : itemStyles - } - > - Docs - - {data.permissions.canUpdateTemplate && ( - - isActive ? activeItemStyles : itemStyles - } - > - Source Code - - )} - - isActive ? activeItemStyles : itemStyles - } - > - Versions - - - isActive ? activeItemStyles : itemStyles - } - > - Embed - - {shouldShowInsights && ( - - isActive ? activeItemStyles : itemStyles - } - > - Insights - - )} - - -
+ + + Summary + + Docs + {data.permissions.canUpdateTemplate && ( + Source Code + )} + Versions + Embed + {shouldShowInsights && ( + Insights + )} +