From edbcd9d88560760aa2816aae53f04d9b03b9fee8 Mon Sep 17 00:00:00 2001 From: Parkreiner Date: Thu, 17 Oct 2024 23:26:35 +0000 Subject: [PATCH 1/4] fix: update all font sizes to be defined by theme --- .../app/src/components/catalog/EntityPage.tsx | 2 +- .../components/A11yInfoCard/A11yInfoCard.tsx | 8 ++--- .../CoderAuthForm/CoderAuthForm.tsx | 3 ++ .../CoderAuthForm/CoderAuthSuccessStatus.tsx | 12 +++----- .../CoderAuthFormDialog.tsx | 4 +++ .../CoderWorkspacesCard/HeaderRow.tsx | 9 ++++-- .../CoderWorkspacesCard/Placeholder.tsx | 3 +- .../WorkspacesListIcon.tsx | 3 +- .../src/components/Disclosure/Disclosure.tsx | 3 +- .../src/utils/styling.ts | 30 +++++++++++++++++++ 10 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 plugins/backstage-plugin-coder/src/utils/styling.ts diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 6c4f9df1..9857795d 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -159,7 +159,7 @@ const overviewContent = ( - + diff --git a/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx b/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx index 4c5959b9..5ee8cb7f 100644 --- a/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx +++ b/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx @@ -23,10 +23,10 @@ const useStyles = makeStyles(theme => ({ }, headerContent: { - // Ideally wouldn't be using hard-coded font sizes, but couldn't figure out - // how to use the theme.typography property, especially since not all - // sub-properties have font sizes defined - fontSize: '1.5rem', + // Not a fan of using a random
element's styles, but it's the only + // typographic category that has a font size of 1.5x the base font size. We + // need that size to match the header sizes of the official InfoCard. + fontSize: theme.typography.h5.fontSize ?? '1.5rem', color: theme.palette.text.primary, fontWeight: 700, borderBottom: `1px solid ${theme.palette.divider}`, diff --git a/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthForm.tsx b/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthForm.tsx index 638a1a75..9c67f584 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthForm.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthForm.tsx @@ -45,6 +45,9 @@ export const CoderAuthForm = ({ descriptionId }: CoderAuthFormProps) => { return ; } + // It shouldn't be possible for these branches to run, because parent + // code should show main content instead of the form when the user is + // authenticated. Still adding them for extra assurance case 'authenticated': case 'distrustedWithGracePeriod': { return ; diff --git a/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthSuccessStatus.tsx b/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthSuccessStatus.tsx index d2c71513..1c3877c8 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthSuccessStatus.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderAuthForm/CoderAuthSuccessStatus.tsx @@ -26,7 +26,7 @@ const useStyles = makeStyles(theme => ({ marginLeft: 'auto', marginRight: 'auto', color: theme.palette.text.primary, - fontSize: '1rem', + fontSize: theme.typography.body1.fontSize, }, statusArea: { @@ -35,13 +35,9 @@ const useStyles = makeStyles(theme => ({ alignItems: 'center', }, - logo: { - // - }, - text: { textAlign: 'center', - lineHeight: '1rem', + lineHeight: theme.typography.body1.fontSize, }, })); @@ -51,8 +47,8 @@ export function CoderAuthSuccessStatus() { return (
- -

You are fully authenticated with Coder!

+ +

You are fully authenticated with Coder.

diff --git a/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx b/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx index 7c39fc95..db30101b 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx @@ -60,6 +60,10 @@ const useStyles = makeStyles(theme => ({ }, closeButton: { + // MUI's typography object doesn't expose any letter tracking values, even + // though you need them to make sure that all-caps text doesn't bunch up. + // Even if the text of the button changes, the styles might look slightly + // wonky, but they won't cause any obvious readability/styling issues letterSpacing: '0.05em', padding: `${theme.spacing(0.5)}px ${theme.spacing(1)}px`, color: theme.palette.primary.main, diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx index b96f2361..276d7bea 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx @@ -18,14 +18,17 @@ const useStyles = makeStyles(theme => ({ }, header: { - fontSize: '1.5rem', - lineHeight: 1, + // Want the header text to be set solid (typography term for setting line + // height equal to font size) to reduce gaps between it and the subtitle, + // but only MUI's h3 line height is the smallest value/closest match + lineHeight: theme.typography.h3.lineHeight ?? 1, + fontSize: theme.typography.h5.fontSize ?? '1.5rem', margin: 0, }, subheader: { margin: '0', - fontSize: '0.875rem', + fontSize: theme.typography.subtitle2.fontSize ?? '0.875rem', fontWeight: 400, color: theme.palette.text.secondary, paddingTop: theme.spacing(0.5), diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/Placeholder.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/Placeholder.tsx index ac4f44fe..9973df2e 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/Placeholder.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/Placeholder.tsx @@ -11,6 +11,7 @@ import { useWorkspacesCardContext } from './Root'; import { makeStyles } from '@material-ui/core'; import { CoderLogo } from '../CoderLogo'; import { VisuallyHidden } from '../VisuallyHidden'; +import { scaleCssUnit } from '../../utils/styling'; const usePlaceholderStyles = makeStyles(theme => ({ root: { @@ -24,7 +25,7 @@ const usePlaceholderStyles = makeStyles(theme => ({ textAlign: 'center', padding: `0 ${theme.spacing(2.5)}px`, fontWeight: 400, - fontSize: '1.125rem', + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 1.125), color: theme.palette.text.secondary, lineHeight: 1.1, }, diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListIcon.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListIcon.tsx index 079189a9..6da0d66d 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListIcon.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListIcon.tsx @@ -1,6 +1,7 @@ import React, { ForwardedRef, HTMLAttributes, useState } from 'react'; import { useUrlSync } from '../../hooks/useUrlSync'; import { Theme, makeStyles } from '@material-ui/core'; +import { scaleCssUnit } from '../../utils/styling'; type WorkspaceListIconProps = Readonly< Omit, 'children' | 'aria-hidden'> & { @@ -21,7 +22,7 @@ const useStyles = makeStyles(theme => ({ root: { width: theme.spacing(2.5), height: theme.spacing(2.5), - fontSize: '0.625rem', + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 0.625), backgroundColor: theme.palette.background.default, borderRadius: '9999px', display: 'flex', diff --git a/plugins/backstage-plugin-coder/src/components/Disclosure/Disclosure.tsx b/plugins/backstage-plugin-coder/src/components/Disclosure/Disclosure.tsx index c53eca54..40d1765c 100644 --- a/plugins/backstage-plugin-coder/src/components/Disclosure/Disclosure.tsx +++ b/plugins/backstage-plugin-coder/src/components/Disclosure/Disclosure.tsx @@ -1,13 +1,14 @@ import React, { type HTMLAttributes, type ReactNode, useState } from 'react'; import { useId } from '../../hooks/hookPolyfills'; import { makeStyles } from '@material-ui/core'; +import { scaleCssUnit } from '../../utils/styling'; const useStyles = makeStyles(theme => ({ disclosureTriangle: { display: 'inline-block', textAlign: 'right', width: theme.spacing(2.25), - fontSize: '0.7rem', + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 0.7), }, disclosureBody: { diff --git a/plugins/backstage-plugin-coder/src/utils/styling.ts b/plugins/backstage-plugin-coder/src/utils/styling.ts new file mode 100644 index 00000000..6b7436bd --- /dev/null +++ b/plugins/backstage-plugin-coder/src/utils/styling.ts @@ -0,0 +1,30 @@ +export function scaleCssUnit( + baseSize: string | number | undefined, + scale: number, +): string { + if (!Number.isFinite(scale)) { + return '1rem'; + } + + if (baseSize === undefined) { + return `${scale}rem`; + } + + if (typeof baseSize === 'number') { + if (!Number.isFinite(baseSize)) { + return `${scale}rem`; + } + + return `${baseSize * scale}px`; + } + + const sizeRe = /^\s*(?\d+(?:\.\d+))?s*(?px|r?em)\s*$/i; + const { value, unit } = sizeRe.exec(baseSize)?.groups ?? {}; + const numValue = Number(value); + + if (Number.isNaN(numValue) || unit === undefined) { + return `${scale}rem`; + } + + return `${scale * numValue}${unit}`; +} From fb4990b47b708cdb5d28b64397f8cc0b6bd02327 Mon Sep 17 00:00:00 2001 From: Parkreiner Date: Thu, 17 Oct 2024 23:49:07 +0000 Subject: [PATCH 2/4] fix: finish updating styles for components --- .../components/CoderAuthFormDialog/CoderAuthFormDialog.tsx | 2 +- .../components/CoderWorkspacesCard/CreateWorkspaceLink.tsx | 2 +- .../components/CoderWorkspacesCard/ExtraActionsButton.tsx | 2 +- .../src/components/CoderWorkspacesCard/SearchBox.tsx | 5 +++-- .../components/CoderWorkspacesCard/WorkspacesListItem.tsx | 2 +- plugins/backstage-plugin-coder/src/utils/styling.ts | 7 +++++++ 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx b/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx index db30101b..94c355db 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx @@ -41,7 +41,7 @@ const useStyles = makeStyles(theme => ({ }, dialogTitle: { - fontSize: '24px', + fontSize: theme.typography.h5.fontSize ?? '24px', borderBottom: `${theme.palette.divider} 1px solid`, padding: `${theme.spacing(1)}px ${theme.spacing(3)}px`, }, diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/CreateWorkspaceLink.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/CreateWorkspaceLink.tsx index a0a1ab84..7a279b8e 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/CreateWorkspaceLink.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/CreateWorkspaceLink.tsx @@ -29,7 +29,7 @@ const useStyles = makeStyles(theme => { justifyContent: 'center', alignItems: 'center', backgroundColor: 'inherit', - borderRadius: '9999px', + borderRadius: theme.shape.borderRadius, lineHeight: 1, color: canCreateWorkspace ? theme.palette.text.primary diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/ExtraActionsButton.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/ExtraActionsButton.tsx index a6ccfb19..b62be388 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/ExtraActionsButton.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/ExtraActionsButton.tsx @@ -33,7 +33,7 @@ const useStyles = makeStyles(theme => { width: theme.spacing(4) + padding, height: theme.spacing(4) + padding, border: 'none', - borderRadius: '9999px', + borderRadius: theme.shape.borderRadius, backgroundColor: 'inherit', lineHeight: 1, diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/SearchBox.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/SearchBox.tsx index d6f17b07..de7b3385 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/SearchBox.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/SearchBox.tsx @@ -14,6 +14,7 @@ import { Theme, makeStyles } from '@material-ui/core'; import { useWorkspacesCardContext } from './Root'; import SearchIcon from '@material-ui/icons/Search'; import CloseIcon from '@material-ui/icons/Close'; +import { CUSTOM_FOCUS_COLOR } from '../../utils/styling'; const LABEL_TEXT = 'Search your Coder workspaces'; const SEARCH_DEBOUNCE_MS = 400; @@ -50,7 +51,7 @@ const useStyles = makeStyles(theme => ({ }, '&:focus-within': { - boxShadow: '0 0 0 1px hsl(213deg, 94%, 68%)', + boxShadow: `0 0 0 1px ${CUSTOM_FOCUS_COLOR}`, }, // Makes it so that the container doesn't have visible focus while you're @@ -93,7 +94,7 @@ const useStyles = makeStyles(theme => ({ cursor: 'pointer', '&:focus': { - boxShadow: '0 0 0 1px hsl(213deg, 94%, 68%)', + boxShadow: `0 0 0 1px ${CUSTOM_FOCUS_COLOR}`, }, }), })); diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListItem.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListItem.tsx index a5a588ae..ba495bc1 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListItem.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/WorkspacesListItem.tsx @@ -82,7 +82,7 @@ const useStyles = makeStyles(theme => ({ alignItems: 'center', gap: theme.spacing(1), color: theme.palette.text.secondary, - fontSize: '16px', + fontSize: theme.typography.body1.fontSize ?? '1rem', }, onlineStatusLight: ({ isAvailable }) => ({ diff --git a/plugins/backstage-plugin-coder/src/utils/styling.ts b/plugins/backstage-plugin-coder/src/utils/styling.ts index 6b7436bd..dad9f866 100644 --- a/plugins/backstage-plugin-coder/src/utils/styling.ts +++ b/plugins/backstage-plugin-coder/src/utils/styling.ts @@ -1,3 +1,10 @@ +/** + * A custom focus color chosen to look close to a system default, while + * remaining visible in dark and light themes. The focus values from Backstage's + * theme object are too low-contrast to meet accessibility requirements. + */ +export const CUSTOM_FOCUS_COLOR = 'hsl(213deg, 94%, 68%)'; + export function scaleCssUnit( baseSize: string | number | undefined, scale: number, From 3386d4220aeea466c399536e3fb82698eb195318 Mon Sep 17 00:00:00 2001 From: Parkreiner Date: Thu, 17 Oct 2024 23:57:50 +0000 Subject: [PATCH 3/4] fix: revert temp config change --- packages/app/src/components/catalog/EntityPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 9857795d..6c4f9df1 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -159,7 +159,7 @@ const overviewContent = ( - + From 40aaa1177214cfa1c0ed321c19231ca74cd4dc4f Mon Sep 17 00:00:00 2001 From: Parkreiner Date: Fri, 18 Oct 2024 14:24:08 +0000 Subject: [PATCH 4/4] fix: update styles to be more based on body values --- .../src/components/A11yInfoCard/A11yInfoCard.tsx | 6 ++---- .../CoderAuthFormDialog/CoderAuthFormDialog.tsx | 3 ++- .../src/components/CoderWorkspacesCard/HeaderRow.tsx | 12 ++++++------ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx b/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx index 5ee8cb7f..fb18a4c5 100644 --- a/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx +++ b/plugins/backstage-plugin-coder/src/components/A11yInfoCard/A11yInfoCard.tsx @@ -6,6 +6,7 @@ */ import React, { type HTMLAttributes, type ReactNode, forwardRef } from 'react'; import { makeStyles } from '@material-ui/core'; +import { scaleCssUnit } from '../../utils/styling'; export type A11yInfoCardProps = Readonly< HTMLAttributes & { @@ -23,10 +24,7 @@ const useStyles = makeStyles(theme => ({ }, headerContent: { - // Not a fan of using a random
element's styles, but it's the only - // typographic category that has a font size of 1.5x the base font size. We - // need that size to match the header sizes of the official InfoCard. - fontSize: theme.typography.h5.fontSize ?? '1.5rem', + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 1.5), color: theme.palette.text.primary, fontWeight: 700, borderBottom: `1px solid ${theme.palette.divider}`, diff --git a/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx b/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx index 94c355db..cb3d501a 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderAuthFormDialog/CoderAuthFormDialog.tsx @@ -7,6 +7,7 @@ import DialogContent from '@material-ui/core/DialogContent'; import DialogTitle from '@material-ui/core/DialogTitle'; import DialogActions from '@material-ui/core/DialogActions'; import { CoderAuthForm } from '../CoderAuthForm/CoderAuthForm'; +import { scaleCssUnit } from '../../utils/styling'; const useStyles = makeStyles(theme => ({ trigger: { @@ -41,7 +42,7 @@ const useStyles = makeStyles(theme => ({ }, dialogTitle: { - fontSize: theme.typography.h5.fontSize ?? '24px', + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 1.5), borderBottom: `${theme.palette.divider} 1px solid`, padding: `${theme.spacing(1)}px ${theme.spacing(3)}px`, }, diff --git a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx index 276d7bea..f1ffcbb6 100644 --- a/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx +++ b/plugins/backstage-plugin-coder/src/components/CoderWorkspacesCard/HeaderRow.tsx @@ -2,6 +2,7 @@ import React, { HTMLAttributes, ReactNode } from 'react'; import { type Theme, makeStyles } from '@material-ui/core'; import { useWorkspacesCardContext } from './Root'; import type { HtmlHeader } from '../../typesConstants'; +import { scaleCssUnit } from '../../utils/styling'; type StyleKey = 'root' | 'header' | 'hgroup' | 'subheader'; const useStyles = makeStyles(theme => ({ @@ -18,17 +19,16 @@ const useStyles = makeStyles(theme => ({ }, header: { - // Want the header text to be set solid (typography term for setting line - // height equal to font size) to reduce gaps between it and the subtitle, - // but only MUI's h3 line height is the smallest value/closest match - lineHeight: theme.typography.h3.lineHeight ?? 1, - fontSize: theme.typography.h5.fontSize ?? '1.5rem', + // Setting line height solid (when leading and font size are equal) to make + // it easier for header and subtitle to sit next to each other + lineHeight: 1, + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 1.5), margin: 0, }, subheader: { margin: '0', - fontSize: theme.typography.subtitle2.fontSize ?? '0.875rem', + fontSize: scaleCssUnit(theme.typography.body1.fontSize, 0.875), fontWeight: 400, color: theme.palette.text.secondary, paddingTop: theme.spacing(0.5),