refactor: stabilize `theme.roles` (#11969)

This commit is contained in:
Kayla Washburn-Love 2024-02-01 09:53:26 -07:00 committed by GitHub
parent 6c9f60a9c5
commit e070a55142
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 689 additions and 672 deletions

View File

@ -127,9 +127,9 @@ export const ActiveUserChart: FC<ActiveUserChartProps> = ({
{
label: `${interval === "day" ? "Daily" : "Weekly"} Active Users`,
data: chartData,
pointBackgroundColor: theme.experimental.roles.active.outline,
pointBorderColor: theme.experimental.roles.active.outline,
borderColor: theme.experimental.roles.active.outline,
pointBackgroundColor: theme.roles.active.outline,
pointBorderColor: theme.roles.active.outline,
borderColor: theme.roles.active.outline,
},
],
}}

View File

@ -19,19 +19,19 @@ const styles = {
},
enabledBadge: (theme) => ({
border: `1px solid ${theme.experimental.roles.success.outline}`,
backgroundColor: theme.experimental.roles.success.background,
color: theme.experimental.roles.success.text,
border: `1px solid ${theme.roles.success.outline}`,
backgroundColor: theme.roles.success.background,
color: theme.roles.success.text,
}),
errorBadge: (theme) => ({
border: `1px solid ${theme.experimental.roles.error.outline}`,
backgroundColor: theme.experimental.roles.error.background,
color: theme.experimental.roles.error.text,
border: `1px solid ${theme.roles.error.outline}`,
backgroundColor: theme.roles.error.background,
color: theme.roles.error.text,
}),
warnBadge: (theme) => ({
border: `1px solid ${theme.experimental.roles.warning.outline}`,
backgroundColor: theme.experimental.roles.warning.background,
color: theme.experimental.roles.warning.text,
border: `1px solid ${theme.roles.warning.outline}`,
backgroundColor: theme.roles.warning.background,
color: theme.roles.warning.text,
}),
} satisfies Record<string, Interpolation<Theme>>;
@ -97,9 +97,9 @@ export const EnterpriseBadge: FC = () => {
css={[
styles.badge,
(theme) => ({
backgroundColor: theme.experimental.roles.info.background,
border: `1px solid ${theme.experimental.roles.info.outline}`,
color: theme.experimental.roles.info.text,
backgroundColor: theme.roles.info.background,
border: `1px solid ${theme.roles.info.outline}`,
color: theme.roles.info.text,
}),
]}
>
@ -114,9 +114,9 @@ export const PreviewBadge: FC = () => {
css={[
styles.badge,
(theme) => ({
border: `1px solid ${theme.experimental.roles.preview.outline}`,
backgroundColor: theme.experimental.roles.preview.background,
color: theme.experimental.roles.preview.text,
border: `1px solid ${theme.roles.preview.outline}`,
backgroundColor: theme.roles.preview.background,
color: theme.roles.preview.text,
}),
]}
>
@ -131,9 +131,9 @@ export const AlphaBadge: FC = () => {
css={[
styles.badge,
(theme) => ({
border: `1px solid ${theme.experimental.roles.preview.outline}`,
backgroundColor: theme.experimental.roles.preview.background,
color: theme.experimental.roles.preview.text,
border: `1px solid ${theme.roles.preview.outline}`,
backgroundColor: theme.roles.preview.background,
color: theme.roles.preview.text,
}),
]}
>
@ -148,9 +148,9 @@ export const DeprecatedBadge: FC = () => {
css={[
styles.badge,
(theme) => ({
border: `1px solid ${theme.experimental.roles.danger.outline}`,
backgroundColor: theme.experimental.roles.danger.background,
color: theme.experimental.roles.danger.text,
border: `1px solid ${theme.roles.danger.outline}`,
backgroundColor: theme.roles.danger.background,
color: theme.roles.danger.text,
}),
]}
>

View File

@ -108,10 +108,10 @@ export const DeleteDialog: FC<DeleteDialogProps> = ({
const styles = {
callout: (theme) => ({
backgroundColor: theme.experimental.roles.danger.background,
border: `1px solid ${theme.experimental.roles.danger.outline}`,
backgroundColor: theme.roles.danger.background,
border: `1px solid ${theme.roles.danger.outline}`,
borderRadius: theme.shape.borderRadius,
color: theme.experimental.roles.danger.text,
color: theme.roles.danger.text,
padding: "8px 16px",
}),
} satisfies Record<string, Interpolation<Theme>>;

View File

@ -72,24 +72,24 @@ export const DialogActionButtons: FC<DialogActionButtonsProps> = ({
const styles = {
dangerButton: (theme) => ({
"&.MuiButton-contained": {
backgroundColor: theme.experimental.roles.danger.fill.solid,
borderColor: theme.experimental.roles.danger.fill.outline,
backgroundColor: theme.roles.danger.fill.solid,
borderColor: theme.roles.danger.fill.outline,
"&:not(.MuiLoadingButton-loading)": {
color: theme.experimental.roles.danger.fill.text,
color: theme.roles.danger.fill.text,
},
"&:hover:not(:disabled)": {
backgroundColor: theme.experimental.roles.danger.hover.fill.solid,
borderColor: theme.experimental.roles.danger.hover.fill.outline,
backgroundColor: theme.roles.danger.hover.fill.solid,
borderColor: theme.roles.danger.hover.fill.outline,
},
"&.Mui-disabled": {
backgroundColor: theme.experimental.roles.danger.disabled.background,
borderColor: theme.experimental.roles.danger.disabled.outline,
backgroundColor: theme.roles.danger.disabled.background,
borderColor: theme.roles.danger.disabled.outline,
"&:not(.MuiLoadingButton-loading)": {
color: theme.experimental.roles.danger.disabled.fill.text,
color: theme.roles.danger.disabled.fill.text,
},
},
},

View File

@ -207,7 +207,7 @@ const styles = {
display: "flex",
alignItems: "center",
...(theme.typography.body2 as CSSObject),
color: theme.experimental.roles.active.fill.outline,
color: theme.roles.active.fill.outline,
}),
linkIcon: {

View File

@ -8,7 +8,7 @@ import {
HelpTooltipTrigger,
} from "components/HelpTooltip/HelpTooltip";
import { css, type Interpolation, type Theme, useTheme } from "@emotion/react";
import type { ThemeRole } from "theme/experimental";
import type { ThemeRole } from "theme/roles";
interface InfoTooltipProps {
type?: ThemeRole;
@ -22,7 +22,7 @@ export const InfoTooltip: FC<InfoTooltipProps> = ({
type = "info",
}) => {
const theme = useTheme();
const iconColor = theme.experimental.roles[type].outline;
const iconColor = theme.roles[type].outline;
return (
<HelpTooltip>

View File

@ -23,13 +23,13 @@ export const LastSeen: FC<LastSeenProps> = ({ at, ...attrs }) => {
// Since the agent reports on a 10m interval,
// the last_used_at can be inaccurate when recent.
message = "Now";
color = theme.experimental.roles.success.fill.solid;
color = theme.roles.success.fill.solid;
} else if (t.isAfter(now.subtract(3, "day"))) {
color = theme.experimental.l2.text;
} else if (t.isAfter(now.subtract(1, "month"))) {
color = theme.experimental.roles.warning.fill.solid;
color = theme.roles.warning.fill.solid;
} else if (t.isAfter(now.subtract(100, "year"))) {
color = theme.experimental.roles.error.fill.solid;
color = theme.roles.error.fill.solid;
} else {
message = "Never";
}

View File

@ -74,14 +74,14 @@ const BasePageButton: FC<BasePageButtonProps> = ({
<Button
css={
highlighted && {
borderColor: theme.experimental.roles.active.outline,
backgroundColor: theme.experimental.roles.active.background,
borderColor: theme.roles.active.outline,
backgroundColor: theme.roles.active.background,
// Override the hover state with active colors, but not hover
// colors because clicking won't do anything.
"&:hover": {
borderColor: theme.experimental.roles.active.outline,
backgroundColor: theme.experimental.roles.active.background,
borderColor: theme.roles.active.outline,
backgroundColor: theme.roles.active.background,
},
}
}

View File

@ -81,8 +81,8 @@ const styles = {
maxWidth: 920,
margin: "auto",
padding: 24,
backgroundImage: `linear-gradient(160deg, transparent, ${theme.experimental.roles.active.background})`,
border: `1px solid ${theme.experimental.roles.active.fill.outline}`,
backgroundImage: `linear-gradient(160deg, transparent, ${theme.roles.active.background})`,
border: `1px solid ${theme.roles.active.fill.outline}`,
borderRadius: 8,
gap: 32,
}),
@ -115,7 +115,7 @@ const styles = {
fontWeight: 500,
},
featureIcon: (theme) => ({
color: theme.experimental.roles.active.fill.outline,
color: theme.roles.active.fill.outline,
}),
feature: {
display: "flex",

View File

@ -9,7 +9,7 @@ import {
type ReactNode,
useMemo,
} from "react";
import type { ThemeRole } from "theme/experimental";
import type { ThemeRole } from "theme/roles";
export type PillProps = HTMLAttributes<HTMLDivElement> & {
icon?: ReactNode;
@ -17,7 +17,7 @@ export type PillProps = HTMLAttributes<HTMLDivElement> & {
};
const themeStyles = (type: ThemeRole) => (theme: Theme) => {
const palette = theme.experimental.roles[type];
const palette = theme.roles[type];
return {
backgroundColor: palette.background,
borderColor: palette.outline,

View File

@ -379,7 +379,7 @@ const HealthIssue: FC<PropsWithChildren> = ({ children }) => {
<Stack direction="row" spacing={1} alignItems="center">
<ErrorIcon
css={{ width: 16, height: 16 }}
htmlColor={theme.experimental.roles.error.outline}
htmlColor={theme.roles.error.outline}
/>
{children}
</Stack>

View File

@ -47,10 +47,10 @@ export const LicenseBannerView: FC<LicenseBannerViewProps> = ({
display: flex;
align-items: center;
padding: 12px;
background-color: ${theme.experimental.roles[type].background};
background-color: ${theme.roles[type].background};
`;
const textColor = theme.experimental.roles[type].text;
const textColor = theme.roles[type].text;
if (messages.length === 1) {
return (

View File

@ -248,7 +248,7 @@ const styles = {
},
metadataValueSuccess: (theme) => ({
color: theme.experimental.roles.success.fill.outline,
color: theme.roles.success.fill.outline,
}),
metadataValueError: (theme) => ({

View File

@ -1,10 +1,14 @@
import { Interpolation, Theme } from "@emotion/react";
import Button from "@mui/material/Button";
import { JFrogXrayScan } from "api/typesGenerated";
import { type Interpolation, type Theme } from "@emotion/react";
import { type FC } from "react";
import type { JFrogXrayScan } from "api/typesGenerated";
import { ExternalImage } from "components/ExternalImage/ExternalImage";
import { FC } from "react";
export const XRayScanAlert: FC<{ scan: JFrogXrayScan }> = ({ scan }) => {
interface XRayScanAlertProps {
scan: JFrogXrayScan;
}
export const XRayScanAlert: FC<XRayScanAlertProps> = ({ scan }) => {
return (
<div role="alert" css={styles.root}>
<ExternalImage
@ -91,13 +95,13 @@ const styles = {
},
},
critical: (theme) => ({
color: theme.experimental.roles.error.fill.solid,
color: theme.roles.error.fill.solid,
}),
high: (theme) => ({
color: theme.experimental.roles.warning.fill.solid,
color: theme.roles.warning.fill.solid,
}),
medium: (theme) => ({
color: theme.experimental.roles.notice.fill.solid,
color: theme.roles.notice.fill.solid,
}),
link: {
marginLeft: "auto",

View File

@ -110,8 +110,8 @@ const styles = {
}),
activeTag: (theme) => ({
borderColor: theme.experimental.roles.active.outline,
backgroundColor: theme.experimental.roles.active.background,
borderColor: theme.roles.active.outline,
backgroundColor: theme.roles.active.background,
}),
description: (theme) => ({

View File

@ -130,29 +130,29 @@ const styles = {
padding: "0 32px",
"&.error": {
backgroundColor: theme.experimental.roles.error.background,
color: theme.experimental.roles.error.text,
backgroundColor: theme.roles.error.background,
color: theme.roles.error.text,
"& .dashed-line": {
backgroundColor: theme.experimental.roles.error.outline,
backgroundColor: theme.roles.error.outline,
},
},
"&.debug": {
backgroundColor: theme.experimental.roles.info.background,
color: theme.experimental.roles.info.text,
backgroundColor: theme.roles.info.background,
color: theme.roles.info.text,
"& .dashed-line": {
backgroundColor: theme.experimental.roles.info.outline,
backgroundColor: theme.roles.info.outline,
},
},
"&.warn": {
backgroundColor: theme.experimental.roles.warning.background,
color: theme.experimental.roles.warning.text,
backgroundColor: theme.roles.warning.background,
color: theme.roles.warning.text,
"& .dashed-line": {
backgroundColor: theme.experimental.roles.warning.outline,
backgroundColor: theme.roles.warning.outline,
},
},
}),

View File

@ -114,7 +114,7 @@ export const WorkspaceOutdatedTooltipContent: FC<TooltipProps> = ({
const styles = {
icon: (theme) => ({
color: theme.experimental.roles.notice.outline,
color: theme.roles.notice.outline,
}),
container: {

View File

@ -161,7 +161,7 @@ export const WorkspaceStatusText: FC<WorkspaceStatusBadgeProps> = ({
css={(theme) => ({
fontWeight: 600,
color: type
? theme.experimental.roles[type].fill.solid
? theme.roles[type].fill.solid
: theme.experimental.l1.text,
})}
>

View File

@ -4,7 +4,7 @@ import TableCell from "@mui/material/TableCell";
import { type FC, useState } from "react";
import userAgentParser from "ua-parser-js";
import type { AuditLog } from "api/typesGenerated";
import { type ThemeRole } from "theme/experimental";
import { type ThemeRole } from "theme/roles";
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow";
import { Pill } from "components/Pill/Pill";
import { Stack } from "components/Stack/Stack";

View File

@ -118,7 +118,7 @@ const styles = {
}),
providerConnectedLabelIcon: (theme) => ({
color: theme.experimental.roles.success.fill.solid,
color: theme.roles.success.fill.solid,
fontSize: 16,
}),
} as Record<string, Interpolation<Theme>>;

View File

@ -152,10 +152,10 @@ const styles = {
}),
sourceConfigOption: (theme) => ({
border: `1px solid ${theme.experimental.roles.active.fill.outline}`,
border: `1px solid ${theme.roles.active.fill.outline}`,
"& .OptionConfigFlag": {
background: theme.experimental.roles.active.fill.solid,
background: theme.roles.active.fill.solid,
},
}),

View File

@ -420,10 +420,7 @@ const TemplateUsagePanel: FC<TemplateUsagePanelProps> = ({
const totalInSeconds =
validUsage?.reduce((total, usage) => total + usage.seconds, 0) ?? 1;
const usageColors = chroma
.scale([
theme.experimental.roles.success.fill.solid,
theme.experimental.roles.notice.fill.solid,
])
.scale([theme.roles.success.fill.solid, theme.roles.notice.fill.solid])
.mode("lch")
.colors(validUsage?.length ?? 0);
// The API returns a row for each app, even if the user didn't use it.

View File

@ -92,8 +92,8 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
}
&.Mui-selected {
color: ${theme.experimental.roles.active.text};
background: ${theme.experimental.roles.active.background};
color: ${theme.roles.active.text};
background: ${theme.roles.active.background};
}
&.Mui-focused {

View File

@ -2,7 +2,7 @@ import { type FC, type ReactNode } from "react";
import ErrorIcon from "@mui/icons-material/ErrorOutline";
import CheckIcon from "@mui/icons-material/CheckOutlined";
import type { TemplateVersion } from "api/typesGenerated";
import { type ThemeRole } from "theme/experimental";
import { type ThemeRole } from "theme/roles";
import { Pill, PillSpinner } from "components/Pill/Pill";
interface TemplateVersionStatusBadgeProps {

View File

@ -216,7 +216,7 @@ const styles = {
userSelect: "none",
}),
containerActive: (theme) => ({
outline: `2px solid ${theme.experimental.roles.active.outline}`,
outline: `2px solid ${theme.roles.active.outline}`,
}),
page: (theme) => ({
backgroundColor: theme.palette.background.default,

View File

@ -13,7 +13,7 @@ import {
type UseFilterMenuOptions,
useFilterMenu,
} from "components/Filter/menu";
import type { ThemeRole } from "theme/experimental";
import type { ThemeRole } from "theme/roles";
import { docs } from "utils/docs";
const userFilterQuery = {
@ -129,7 +129,7 @@ const StatusIndicator: FC<StatusIndicatorProps> = ({ option }) => {
height: 8,
width: 8,
borderRadius: 4,
backgroundColor: theme.experimental.roles[option.color].fill.solid,
backgroundColor: theme.roles[option.color].fill.solid,
}}
/>
);

View File

@ -73,10 +73,10 @@ export const UserRoleCell: FC<UserRoleCellProps> = ({
<Pill
css={{
backgroundColor: hasOwnerRole
? theme.experimental.roles.info.background
? theme.roles.info.background
: theme.experimental.l2.background,
borderColor: hasOwnerRole
? theme.experimental.roles.info.outline
? theme.roles.info.outline
: theme.experimental.l2.outline,
}}
>

View File

@ -173,25 +173,25 @@ const styles = {
orphanContainer: (theme) => ({
marginTop: 24,
display: "flex",
backgroundColor: theme.experimental.roles.danger.background,
backgroundColor: theme.roles.danger.background,
justifyContent: "space-between",
border: `1px solid ${theme.experimental.roles.danger.outline}`,
border: `1px solid ${theme.roles.danger.outline}`,
borderRadius: 8,
padding: 12,
gap: 8,
lineHeight: "18px",
"& .option": {
color: theme.experimental.roles.danger.fill.solid,
color: theme.roles.danger.fill.solid,
"&.Mui-checked": {
color: theme.experimental.roles.danger.fill.solid,
color: theme.roles.danger.fill.solid,
},
},
"& .info": {
fontSize: 14,
fontWeight: 600,
color: theme.experimental.roles.danger.text,
color: theme.roles.danger.text,
},
}),
} satisfies Record<string, Interpolation<Theme>>;

View File

@ -1,4 +1,7 @@
import { FC, ReactNode } from "react";
import Button, { type ButtonProps } from "@mui/material/Button";
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
import { type FC, type ReactNode } from "react";
import { type ThemeRole } from "theme/roles";
import { Pill } from "components/Pill/Pill";
import {
Popover,
@ -6,10 +9,7 @@ import {
PopoverTrigger,
usePopover,
} from "components/Popover/Popover";
import { Interpolation, Theme, useTheme } from "@emotion/react";
import Button, { ButtonProps } from "@mui/material/Button";
import { ThemeRole } from "theme/experimental";
import { AlertProps } from "components/Alert/Alert";
import { type AlertProps } from "components/Alert/Alert";
export type NotificationItem = {
title: string;
@ -44,7 +44,7 @@ export const Notifications: FC<NotificationsProps> = ({
horizontal="right"
css={{
"& .MuiPaper-root": {
borderColor: theme.experimental.roles[severity].outline,
borderColor: theme.roles[severity].outline,
maxWidth: 400,
},
}}
@ -57,18 +57,19 @@ export const Notifications: FC<NotificationsProps> = ({
);
};
const NotificationPill = (props: NotificationsProps) => {
const { items, severity, icon } = props;
const NotificationPill: FC<NotificationsProps> = ({
items,
severity,
icon,
}) => {
const popover = usePopover();
return (
<Pill
icon={icon}
css={(theme) => ({
"& svg": { color: theme.experimental.roles[severity].outline },
borderColor: popover.isOpen
? theme.experimental.roles[severity].outline
: undefined,
"& svg": { color: theme.roles[severity].outline },
borderColor: popover.isOpen ? theme.roles[severity].outline : undefined,
})}
>
{items.length}
@ -76,9 +77,11 @@ const NotificationPill = (props: NotificationsProps) => {
);
};
const NotificationItem: FC<{ notification: NotificationItem }> = (props) => {
const { notification } = props;
interface NotificationItemProps {
notification: NotificationItem;
}
const NotificationItem: FC<NotificationItemProps> = ({ notification }) => {
return (
<article css={styles.notificationItem}>
<h4 css={{ margin: 0, fontWeight: 500 }}>{notification.title}</h4>

View File

@ -477,7 +477,7 @@ const styles = {
newVersion: (theme) => ({
fontSize: 13,
fontWeight: 500,
color: theme.experimental.roles.active.fill.solid,
color: theme.roles.active.fill.solid,
}),
message: {

View File

@ -40,16 +40,16 @@ export const LastUsed: FC<LastUsedProps> = ({ lastUsedAt }) => {
);
if (t.isAfter(now.subtract(1, "hour"))) {
circle = <Circle color={theme.experimental.roles.success.fill.solid} />;
circle = <Circle color={theme.roles.success.fill.solid} />;
// Since the agent reports on a 10m interval,
// the last_used_at can be inaccurate when recent.
message = "Now";
} else if (t.isAfter(now.subtract(3, "day"))) {
circle = <Circle color={theme.palette.text.secondary} />;
} else if (t.isAfter(now.subtract(1, "month"))) {
circle = <Circle color={theme.experimental.roles.warning.fill.solid} />;
circle = <Circle color={theme.roles.warning.fill.solid} />;
} else if (t.isAfter(now.subtract(100, "year"))) {
circle = <Circle color={theme.experimental.roles.error.fill.solid} />;
circle = <Circle color={theme.roles.error.fill.solid} />;
} else {
message = "Never";
}

View File

@ -215,7 +215,7 @@ const StatusIndicator: FC<StatusIndicatorProps> = ({ option }) => {
height: 8,
width: 8,
borderRadius: 4,
backgroundColor: theme.experimental.roles[option.color].fill.solid,
backgroundColor: theme.roles[option.color].fill.solid,
}}
/>
);

View File

@ -1,5 +1,5 @@
import { BaseOption } from "components/Filter/options";
import type { ThemeRole } from "theme/experimental";
import type { ThemeRole } from "theme/roles";
export type StatusOption = BaseOption & {
color: ThemeRole;

View File

@ -43,157 +43,4 @@ export default {
},
},
},
roles: {
danger: {
background: colors.orange[950],
outline: colors.orange[500],
text: colors.orange[50],
fill: {
solid: colors.orange[700],
outline: colors.orange[700],
text: colors.white,
},
disabled: {
background: colors.orange[950],
outline: colors.orange[800],
text: colors.orange[200],
fill: {
solid: colors.orange[800],
outline: colors.orange[800],
text: colors.white,
},
},
hover: {
background: colors.orange[900],
outline: colors.orange[500],
text: colors.white,
fill: {
solid: colors.orange[500],
outline: colors.orange[500],
text: colors.white,
},
},
},
error: {
background: colors.red[950],
outline: colors.red[600],
text: colors.red[50],
fill: {
solid: colors.red[400],
outline: colors.red[400],
text: colors.white,
},
},
warning: {
background: colors.amber[950],
outline: colors.amber[300],
text: colors.amber[50],
fill: {
solid: colors.amber[500],
outline: colors.amber[500],
text: colors.white,
},
},
notice: {
background: colors.yellow[950],
outline: colors.yellow[200],
text: colors.yellow[50],
fill: {
solid: colors.yellow[500],
outline: colors.yellow[500],
text: colors.white,
},
},
info: {
background: colors.blue[950],
outline: colors.blue[400],
text: colors.blue[50],
fill: {
solid: colors.blue[600],
outline: colors.blue[600],
text: colors.white,
},
},
success: {
background: colors.green[950],
outline: colors.green[500],
text: colors.green[50],
fill: {
solid: colors.green[600],
outline: colors.green[600],
text: colors.white,
},
disabled: {
background: colors.green[950],
outline: colors.green[800],
text: colors.green[200],
fill: {
solid: colors.green[800],
outline: colors.green[800],
text: colors.white,
},
},
hover: {
background: colors.green[900],
outline: colors.green[500],
text: colors.white,
fill: {
solid: colors.green[500],
outline: colors.green[500],
text: colors.white,
},
},
},
active: {
background: colors.sky[950],
outline: colors.sky[500],
text: colors.sky[50],
fill: {
solid: colors.sky[600],
outline: colors.sky[400],
text: colors.white,
},
disabled: {
background: colors.sky[950],
outline: colors.sky[800],
text: colors.sky[200],
fill: {
solid: colors.sky[800],
outline: colors.sky[800],
text: colors.white,
},
},
hover: {
background: colors.sky[900],
outline: colors.sky[500],
text: colors.white,
fill: {
solid: colors.sky[500],
outline: colors.sky[500],
text: colors.white,
},
},
},
inactive: {
background: colors.zinc[950],
outline: colors.zinc[500],
text: colors.zinc[50],
fill: {
solid: colors.zinc[400],
outline: colors.zinc[400],
text: colors.white,
},
},
preview: {
background: colors.violet[950],
outline: colors.violet[500],
text: colors.violet[50],
fill: {
solid: colors.violet[400],
outline: colors.violet[400],
text: colors.white,
},
},
},
} satisfies NewTheme;

View File

@ -1,11 +1,13 @@
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import { forDarkThemes } from "../externalImages";
import experimental from "./experimental";
import monaco from "./monaco";
import roles from "./roles";
export default {
...muiTheme,
externalImages: forDarkThemes,
experimental,
monaco,
externalImages: forDarkThemes,
roles,
};

View File

@ -0,0 +1,155 @@
import type { Roles } from "../roles";
import colors from "../tailwindColors";
export default {
danger: {
background: colors.orange[950],
outline: colors.orange[500],
text: colors.orange[50],
fill: {
solid: colors.orange[700],
outline: colors.orange[700],
text: colors.white,
},
disabled: {
background: colors.orange[950],
outline: colors.orange[800],
text: colors.orange[200],
fill: {
solid: colors.orange[800],
outline: colors.orange[800],
text: colors.white,
},
},
hover: {
background: colors.orange[900],
outline: colors.orange[500],
text: colors.white,
fill: {
solid: colors.orange[500],
outline: colors.orange[500],
text: colors.white,
},
},
},
error: {
background: colors.red[950],
outline: colors.red[600],
text: colors.red[50],
fill: {
solid: colors.red[400],
outline: colors.red[400],
text: colors.white,
},
},
warning: {
background: colors.amber[950],
outline: colors.amber[300],
text: colors.amber[50],
fill: {
solid: colors.amber[500],
outline: colors.amber[500],
text: colors.white,
},
},
notice: {
background: colors.yellow[950],
outline: colors.yellow[200],
text: colors.yellow[50],
fill: {
solid: colors.yellow[500],
outline: colors.yellow[500],
text: colors.white,
},
},
info: {
background: colors.blue[950],
outline: colors.blue[400],
text: colors.blue[50],
fill: {
solid: colors.blue[600],
outline: colors.blue[600],
text: colors.white,
},
},
success: {
background: colors.green[950],
outline: colors.green[500],
text: colors.green[50],
fill: {
solid: colors.green[600],
outline: colors.green[600],
text: colors.white,
},
disabled: {
background: colors.green[950],
outline: colors.green[800],
text: colors.green[200],
fill: {
solid: colors.green[800],
outline: colors.green[800],
text: colors.white,
},
},
hover: {
background: colors.green[900],
outline: colors.green[500],
text: colors.white,
fill: {
solid: colors.green[500],
outline: colors.green[500],
text: colors.white,
},
},
},
active: {
background: colors.sky[950],
outline: colors.sky[500],
text: colors.sky[50],
fill: {
solid: colors.sky[600],
outline: colors.sky[400],
text: colors.white,
},
disabled: {
background: colors.sky[950],
outline: colors.sky[800],
text: colors.sky[200],
fill: {
solid: colors.sky[800],
outline: colors.sky[800],
text: colors.white,
},
},
hover: {
background: colors.sky[900],
outline: colors.sky[500],
text: colors.white,
fill: {
solid: colors.sky[500],
outline: colors.sky[500],
text: colors.white,
},
},
},
inactive: {
background: colors.zinc[950],
outline: colors.zinc[500],
text: colors.zinc[50],
fill: {
solid: colors.zinc[400],
outline: colors.zinc[400],
text: colors.white,
},
},
preview: {
background: colors.violet[950],
outline: colors.violet[500],
text: colors.violet[50],
fill: {
solid: colors.violet[400],
outline: colors.violet[400],
text: colors.white,
},
},
} satisfies Roles;

View File

@ -43,157 +43,4 @@ export default {
},
},
},
roles: {
danger: {
background: colors.orange[950],
outline: colors.orange[600],
text: colors.orange[50],
fill: {
solid: colors.orange[600],
outline: colors.orange[600],
text: colors.white,
},
disabled: {
background: colors.orange[950],
outline: colors.orange[800],
text: colors.orange[200],
fill: {
solid: colors.orange[800],
outline: colors.orange[800],
text: colors.white,
},
},
hover: {
background: colors.orange[900],
outline: colors.orange[500],
text: colors.white,
fill: {
solid: colors.orange[500],
outline: colors.orange[500],
text: colors.white,
},
},
},
error: {
background: colors.red[950],
outline: colors.red[500],
text: colors.red[50],
fill: {
solid: colors.red[600],
outline: colors.red[600],
text: colors.white,
},
},
warning: {
background: colors.amber[950],
outline: colors.amber[300],
text: colors.amber[50],
fill: {
solid: colors.amber[500],
outline: colors.amber[500],
text: colors.white,
},
},
notice: {
background: colors.yellow[950],
outline: colors.yellow[200],
text: colors.yellow[50],
fill: {
solid: colors.yellow[500],
outline: colors.yellow[500],
text: colors.white,
},
},
info: {
background: colors.blue[950],
outline: colors.blue[400],
text: colors.blue[50],
fill: {
solid: colors.blue[500],
outline: colors.blue[500],
text: colors.white,
},
},
success: {
background: colors.green[950],
outline: colors.green[500],
text: colors.green[50],
fill: {
solid: colors.green[600],
outline: colors.green[600],
text: colors.white,
},
disabled: {
background: colors.green[950],
outline: colors.green[800],
text: colors.green[200],
fill: {
solid: colors.green[800],
outline: colors.green[800],
text: colors.white,
},
},
hover: {
background: colors.green[900],
outline: colors.green[500],
text: colors.white,
fill: {
solid: colors.green[500],
outline: colors.green[500],
text: colors.white,
},
},
},
active: {
background: colors.sky[950],
outline: colors.sky[500],
text: colors.sky[50],
fill: {
solid: colors.sky[600],
outline: colors.sky[600],
text: colors.white,
},
disabled: {
background: colors.sky[950],
outline: colors.sky[800],
text: colors.sky[200],
fill: {
solid: colors.sky[800],
outline: colors.sky[800],
text: colors.white,
},
},
hover: {
background: colors.sky[900],
outline: colors.sky[500],
text: colors.white,
fill: {
solid: colors.sky[500],
outline: colors.sky[500],
text: colors.white,
},
},
},
inactive: {
background: colors.zinc[950],
outline: colors.zinc[500],
text: colors.zinc[50],
fill: {
solid: colors.zinc[400],
outline: colors.zinc[400],
text: colors.white,
},
},
preview: {
background: colors.violet[950],
outline: colors.violet[500],
text: colors.violet[50],
fill: {
solid: colors.violet[400],
outline: colors.violet[400],
text: colors.white,
},
},
},
} satisfies NewTheme;

View File

@ -1,11 +1,13 @@
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import { forDarkThemes } from "../externalImages";
import experimental from "./experimental";
import monaco from "./monaco";
import roles from "./roles";
export default {
...muiTheme,
externalImages: forDarkThemes,
experimental,
monaco,
externalImages: forDarkThemes,
roles,
};

View File

@ -0,0 +1,155 @@
import type { Roles } from "../roles";
import colors from "../tailwindColors";
export default {
danger: {
background: colors.orange[950],
outline: colors.orange[600],
text: colors.orange[50],
fill: {
solid: colors.orange[600],
outline: colors.orange[600],
text: colors.white,
},
disabled: {
background: colors.orange[950],
outline: colors.orange[800],
text: colors.orange[200],
fill: {
solid: colors.orange[800],
outline: colors.orange[800],
text: colors.white,
},
},
hover: {
background: colors.orange[900],
outline: colors.orange[500],
text: colors.white,
fill: {
solid: colors.orange[500],
outline: colors.orange[500],
text: colors.white,
},
},
},
error: {
background: colors.red[950],
outline: colors.red[500],
text: colors.red[50],
fill: {
solid: colors.red[600],
outline: colors.red[600],
text: colors.white,
},
},
warning: {
background: colors.amber[950],
outline: colors.amber[300],
text: colors.amber[50],
fill: {
solid: colors.amber[500],
outline: colors.amber[500],
text: colors.white,
},
},
notice: {
background: colors.yellow[950],
outline: colors.yellow[200],
text: colors.yellow[50],
fill: {
solid: colors.yellow[500],
outline: colors.yellow[500],
text: colors.white,
},
},
info: {
background: colors.blue[950],
outline: colors.blue[400],
text: colors.blue[50],
fill: {
solid: colors.blue[500],
outline: colors.blue[500],
text: colors.white,
},
},
success: {
background: colors.green[950],
outline: colors.green[500],
text: colors.green[50],
fill: {
solid: colors.green[600],
outline: colors.green[600],
text: colors.white,
},
disabled: {
background: colors.green[950],
outline: colors.green[800],
text: colors.green[200],
fill: {
solid: colors.green[800],
outline: colors.green[800],
text: colors.white,
},
},
hover: {
background: colors.green[900],
outline: colors.green[500],
text: colors.white,
fill: {
solid: colors.green[500],
outline: colors.green[500],
text: colors.white,
},
},
},
active: {
background: colors.sky[950],
outline: colors.sky[500],
text: colors.sky[50],
fill: {
solid: colors.sky[600],
outline: colors.sky[600],
text: colors.white,
},
disabled: {
background: colors.sky[950],
outline: colors.sky[800],
text: colors.sky[200],
fill: {
solid: colors.sky[800],
outline: colors.sky[800],
text: colors.white,
},
},
hover: {
background: colors.sky[900],
outline: colors.sky[500],
text: colors.white,
fill: {
solid: colors.sky[500],
outline: colors.sky[500],
text: colors.white,
},
},
},
inactive: {
background: colors.zinc[950],
outline: colors.zinc[500],
text: colors.zinc[50],
fill: {
solid: colors.zinc[400],
outline: colors.zinc[400],
text: colors.white,
},
},
preview: {
background: colors.violet[950],
outline: colors.violet[500],
text: colors.violet[50],
fill: {
solid: colors.violet[400],
outline: colors.violet[400],
text: colors.white,
},
},
} satisfies Roles;

View File

@ -1,83 +1,6 @@
export type ThemeRole = keyof NewTheme["roles"];
export type InteractiveThemeRole = keyof {
[K in keyof NewTheme["roles"] as NewTheme["roles"][K] extends InteractiveRole
? K
: never]: unknown;
};
import type { Role, InteractiveRole } from "./roles";
export interface NewTheme {
l1: Role; // page background, things which sit at the "root level"
l2: InteractiveRole; // sidebars, table headers, navigation
roles: {
/** Something is wrong; either unexpectedly, or in a meaningful way. */
error: Role;
/** Something isn't quite right, but without serious consequence. */
warning: Role;
/** A prompt for action, to correct or look into something. */
notice: Role;
/** Notable information; just so you know! */
info: Role;
/** Confirmation, or affirming that things are as desired. */
success: InteractiveRole;
/** Selected, in progress, of particular relevance right now. */
active: InteractiveRole;
/** For things that can be made "active", but are not currently so.
* Paused, stopped, off, etc.
*/
inactive: Role;
/** Actions that have long lasting or irreversible effects.
* Deletion, immutable parameters, etc.
*/
danger: InteractiveRole;
/** This isn't quite ready for prime-time, but you're welcome to look around!
* Preview features, experiments, unstable, etc.
*/
preview: Role;
};
}
/**
* A set of colors which work together to fill a desirable "communication role"
* ie. I wish to communicate an error, I wish to communicate that this is dangerous, etc.
*/
export interface Role {
/** A background color that works best with the corresponding `outline` and `text` colors */
background: string;
/** A border, or a color for an outlined icon */
outline: string;
/** A color for text on the corresponding `background` */
text: string;
/** A set of more saturated colors to make things stand out */
fill: {
/** A saturated color for use as a background, or for text or icons on a neutral background */
solid: string;
/** A color for outlining an area using the solid background color, or for an outlined icon */
outline: string;
/** A color for text when using the `solid` background color */
text: string;
};
}
/** Provides additional colors which can indicate different states for interactive elements */
export interface InteractiveRole extends Role {
/** A set of colors which can indicate a disabled state */
disabled: Role;
/** A set of colors which can indicate mouse hover (or keyboard focus) */
hover: Role;
}

View File

@ -1,13 +1,15 @@
import type { Theme as MuiTheme } from "@mui/material/styles";
import type * as monaco from "monaco-editor";
import type { NewTheme } from "./experimental";
import type { ExternalImageModeStyles } from "./externalImages";
import type { Roles } from "./roles";
import dark from "./dark";
import darkBlue from "./darkBlue";
import light from "./light";
import type { NewTheme } from "./experimental";
import type { ExternalImageModeStyles } from "./externalImages";
export interface Theme extends MuiTheme {
experimental: NewTheme;
roles: Roles;
monaco: monaco.editor.IStandaloneThemeData;
externalImages: ExternalImageModeStyles;
}

View File

@ -43,157 +43,4 @@ export default {
},
},
},
roles: {
danger: {
background: colors.orange[50],
outline: colors.orange[400],
text: colors.orange[950],
fill: {
solid: colors.orange[600],
outline: colors.orange[600],
text: colors.white,
},
disabled: {
background: colors.orange[50],
outline: colors.orange[800],
text: colors.orange[800],
fill: {
solid: colors.orange[800],
outline: colors.orange[800],
text: colors.white,
},
},
hover: {
background: colors.orange[100],
outline: colors.orange[500],
text: colors.black,
fill: {
solid: colors.orange[500],
outline: colors.orange[500],
text: colors.white,
},
},
},
error: {
background: colors.red[100],
outline: colors.red[500],
text: colors.red[950],
fill: {
solid: colors.red[600],
outline: colors.red[600],
text: colors.white,
},
},
warning: {
background: colors.amber[50],
outline: colors.amber[300],
text: colors.amber[950],
fill: {
solid: colors.amber[500],
outline: colors.amber[500],
text: colors.white,
},
},
notice: {
background: colors.yellow[50],
outline: colors.yellow[600],
text: colors.yellow[950],
fill: {
solid: colors.yellow[500],
outline: colors.yellow[500],
text: colors.white,
},
},
info: {
background: colors.blue[50],
outline: colors.blue[400],
text: colors.blue[950],
fill: {
solid: colors.blue[600],
outline: colors.blue[600],
text: colors.white,
},
},
success: {
background: colors.green[50],
outline: colors.green[500],
text: colors.green[950],
fill: {
solid: colors.green[600],
outline: colors.green[600],
text: colors.white,
},
disabled: {
background: colors.green[50],
outline: colors.green[800],
text: colors.green[800],
fill: {
solid: colors.green[800],
outline: colors.green[800],
text: colors.white,
},
},
hover: {
background: colors.green[100],
outline: colors.green[500],
text: colors.black,
fill: {
solid: colors.green[500],
outline: colors.green[500],
text: colors.white,
},
},
},
active: {
background: colors.sky[100],
outline: colors.sky[500],
text: colors.sky[950],
fill: {
solid: colors.sky[600],
outline: colors.sky[600],
text: colors.white,
},
disabled: {
background: colors.sky[50],
outline: colors.sky[800],
text: colors.sky[200],
fill: {
solid: colors.sky[800],
outline: colors.sky[800],
text: colors.white,
},
},
hover: {
background: colors.sky[200],
outline: colors.sky[400],
text: colors.black,
fill: {
solid: colors.sky[500],
outline: colors.sky[500],
text: colors.white,
},
},
},
inactive: {
background: colors.gray[100],
outline: colors.gray[400],
text: colors.gray[950],
fill: {
solid: colors.gray[600],
outline: colors.gray[600],
text: colors.white,
},
},
preview: {
background: colors.violet[50],
outline: colors.violet[500],
text: colors.violet[950],
fill: {
solid: colors.violet[600],
outline: colors.violet[600],
text: colors.white,
},
},
},
} satisfies NewTheme;

View File

@ -1,11 +1,13 @@
import experimental from "./experimental";
import monaco from "./monaco";
import muiTheme from "./mui";
import { forLightThemes } from "../externalImages";
import experimental from "./experimental";
import monaco from "./monaco";
import roles from "./roles";
export default {
...muiTheme,
externalImages: forLightThemes,
experimental,
monaco,
externalImages: forLightThemes,
roles,
};

View File

@ -0,0 +1,155 @@
import type { Roles } from "../roles";
import colors from "../tailwindColors";
export default {
danger: {
background: colors.orange[50],
outline: colors.orange[400],
text: colors.orange[950],
fill: {
solid: colors.orange[600],
outline: colors.orange[600],
text: colors.white,
},
disabled: {
background: colors.orange[50],
outline: colors.orange[800],
text: colors.orange[800],
fill: {
solid: colors.orange[800],
outline: colors.orange[800],
text: colors.white,
},
},
hover: {
background: colors.orange[100],
outline: colors.orange[500],
text: colors.black,
fill: {
solid: colors.orange[500],
outline: colors.orange[500],
text: colors.white,
},
},
},
error: {
background: colors.red[100],
outline: colors.red[500],
text: colors.red[950],
fill: {
solid: colors.red[600],
outline: colors.red[600],
text: colors.white,
},
},
warning: {
background: colors.amber[50],
outline: colors.amber[300],
text: colors.amber[950],
fill: {
solid: colors.amber[500],
outline: colors.amber[500],
text: colors.white,
},
},
notice: {
background: colors.yellow[50],
outline: colors.yellow[600],
text: colors.yellow[950],
fill: {
solid: colors.yellow[500],
outline: colors.yellow[500],
text: colors.white,
},
},
info: {
background: colors.blue[50],
outline: colors.blue[400],
text: colors.blue[950],
fill: {
solid: colors.blue[600],
outline: colors.blue[600],
text: colors.white,
},
},
success: {
background: colors.green[50],
outline: colors.green[500],
text: colors.green[950],
fill: {
solid: colors.green[600],
outline: colors.green[600],
text: colors.white,
},
disabled: {
background: colors.green[50],
outline: colors.green[800],
text: colors.green[800],
fill: {
solid: colors.green[800],
outline: colors.green[800],
text: colors.white,
},
},
hover: {
background: colors.green[100],
outline: colors.green[500],
text: colors.black,
fill: {
solid: colors.green[500],
outline: colors.green[500],
text: colors.white,
},
},
},
active: {
background: colors.sky[100],
outline: colors.sky[500],
text: colors.sky[950],
fill: {
solid: colors.sky[600],
outline: colors.sky[600],
text: colors.white,
},
disabled: {
background: colors.sky[50],
outline: colors.sky[800],
text: colors.sky[200],
fill: {
solid: colors.sky[800],
outline: colors.sky[800],
text: colors.white,
},
},
hover: {
background: colors.sky[200],
outline: colors.sky[400],
text: colors.black,
fill: {
solid: colors.sky[500],
outline: colors.sky[500],
text: colors.white,
},
},
},
inactive: {
background: colors.gray[100],
outline: colors.gray[400],
text: colors.gray[950],
fill: {
solid: colors.gray[600],
outline: colors.gray[600],
text: colors.white,
},
},
preview: {
background: colors.violet[50],
outline: colors.violet[500],
text: colors.violet[950],
fill: {
solid: colors.violet[600],
outline: colors.violet[600],
text: colors.white,
},
},
} satisfies Roles;

76
site/src/theme/roles.ts Normal file
View File

@ -0,0 +1,76 @@
export type ThemeRole = keyof Roles;
export type InteractiveThemeRole = keyof {
[K in keyof Roles as Roles[K] extends InteractiveRole ? K : never]: unknown;
};
export interface Roles {
/** Something is wrong; either unexpectedly, or in a meaningful way. */
error: Role;
/** Something isn't quite right, but without serious consequence. */
warning: Role;
/** A prompt for action, to correct or look into something. */
notice: Role;
/** Notable information; just so you know! */
info: Role;
/** Confirmation, or affirming that things are as desired. */
success: InteractiveRole;
/** Selected, in progress, of particular relevance right now. */
active: InteractiveRole;
/** For things that can be made "active", but are not currently so.
* Paused, stopped, off, etc.
*/
inactive: Role;
/** Actions that have long lasting or irreversible effects.
* Deletion, immutable parameters, etc.
*/
danger: InteractiveRole;
/** This isn't quite ready for prime-time, but you're welcome to look around!
* Preview features, experiments, unstable, etc.
*/
preview: Role;
}
/**
* A set of colors which work together to fill a desirable "communication role"
* ie. I wish to communicate an error, I wish to communicate that this is dangerous, etc.
*/
export interface Role {
/** A background color that works best with the corresponding `outline` and `text` colors */
background: string;
/** A border, or a color for an outlined icon */
outline: string;
/** A color for text on the corresponding `background` */
text: string;
/** A set of more saturated colors to make things stand out */
fill: {
/** A saturated color for use as a background, or for text or icons on a neutral background */
solid: string;
/** A color for outlining an area using the solid background color, or for an outlined icon */
outline: string;
/** A color for text when using the `solid` background color */
text: string;
};
}
/** Provides additional colors which can indicate different states for interactive elements */
export interface InteractiveRole extends Role {
/** A set of colors which can indicate a disabled state */
disabled: Role;
/** A set of colors which can indicate mouse hover (or keyboard focus) */
hover: Role;
}

View File

@ -5,12 +5,12 @@ export const getLatencyColor = (theme: Theme, latency?: number) => {
return theme.palette.text.secondary;
}
let color = theme.experimental.roles.success.fill.solid;
let color = theme.roles.success.fill.solid;
if (latency >= 150 && latency < 300) {
color = theme.experimental.roles.warning.fill.solid;
color = theme.roles.warning.fill.solid;
} else if (latency >= 300) {
color = theme.experimental.roles.error.fill.solid;
color = theme.roles.error.fill.solid;
}
return color;
};

View File

@ -36,19 +36,19 @@ export const getDisplayWorkspaceBuildStatus = (
case "succeeded":
return {
type: "success",
color: theme.experimental.roles.success.text,
color: theme.roles.success.text,
status: DisplayWorkspaceBuildStatusLanguage.succeeded,
} as const;
case "pending":
return {
type: "secondary",
color: theme.experimental.roles.active.text,
color: theme.roles.active.text,
status: DisplayWorkspaceBuildStatusLanguage.pending,
} as const;
case "running":
return {
type: "info",
color: theme.experimental.roles.active.text,
color: theme.roles.active.text,
status: DisplayWorkspaceBuildStatusLanguage.running,
} as const;
// Just handle unknown as failed
@ -56,19 +56,19 @@ export const getDisplayWorkspaceBuildStatus = (
case "failed":
return {
type: "error",
color: theme.experimental.roles.error.text,
color: theme.roles.error.text,
status: DisplayWorkspaceBuildStatusLanguage.failed,
} as const;
case "canceling":
return {
type: "warning",
color: theme.experimental.roles.warning.text,
color: theme.roles.warning.text,
status: DisplayWorkspaceBuildStatusLanguage.canceling,
} as const;
case "canceled":
return {
type: "secondary",
color: theme.experimental.roles.warning.text,
color: theme.roles.warning.text,
status: DisplayWorkspaceBuildStatusLanguage.canceled,
} as const;
}