Skip to content

fix(site): standardize headers for Admin Settings page #16911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 1, 2025

Conversation

Parkreiner
Copy link
Member

@Parkreiner Parkreiner commented Mar 13, 2025

No issue to link – it's just a small thing that has been on my radar for a bit

Changes made

  • Switched almost all headers to use the SettingHeader component
  • Redesigned component to be more composition-based, to stay in line with the patterns we're starting to use more throughout the codebase
  • Refactored SettingHeader to be based on Radix and Tailwind, rather than Emotion/MUI
  • Added additional props to SettingHeader to help resolve issues with the component creating invalid HTML
  • Beefed up SettingHeader to have better out-of-the-box accessibility
  • Addressed some typographic problems in SettingHeader
  • Addressed some responsive layout problems for SettingsHeader
  • Added first-ever stories for SettingsHeader

Notes

  • There are still a few headers that aren't using SettingHeader yet. There were some UI edge cases that meant I couldn't reliably bring it in without consulting the Design team first. I'm a little less worried about them, because they at least look like the other headers, but it'd be nice if we could centralize everything in a followup PR

Screenshots

Workspace Proxies

Before – Main header does not match the style of the other pages
image

After
image

External Authentication

Before – The max width for the description text is too narrow. Body text for English-language text has an ideal width of 50em–75em, which is an agreed-upon standard that has existed since the 1600s. Most graphic designers and typographers tend to default to 65em
image

After
image

@Parkreiner Parkreiner self-assigned this Mar 13, 2025
@Parkreiner Parkreiner changed the title [DO NOT MERGE] fix(site): standardize how headers are displayed for Admin Settings fix(site): standardize how headers are displayed for Admin Settings [DO NOT MERGE] Mar 13, 2025
@Parkreiner Parkreiner changed the title fix(site): standardize how headers are displayed for Admin Settings [DO NOT MERGE] fix(site): standardize how headers are displayed for Admin Settings page [DO NOT MERGE] Mar 13, 2025
<Stack alignItems="baseline" direction="row" justifyContent="space-between">
<div css={{ maxWidth: 420, marginBottom: 24 }}>
<Stack direction="row" spacing={1} alignItems="center">
<h1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a big accessibility/HTML validity issue. We were using this component multiple times on the same page, but only one h1 is allowed to be on a page, total

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I decoupled the secondary boolean into a styling prop and a semantic prop. There may be cases when we need to change the heading level to make the HTML valid, even though the styling should be exactly the same

<div className="flex flex-row gap-2 align-middle">
<HeaderTitle
className={twMerge(
"m-0 pb-1 text-3xl font-bold flex items-center gap-2 leading-tight",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The different leading values for the header and description are intentional – leading needs to go down the larger your text is

@@ -47,7 +47,7 @@ export const NotificationsPage: FC = () => {
title={
<>
Notifications
<span css={{ position: "relative", top: "-6px" }}>
<span css={{ position: "relative", top: "2px" }}>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to adjust this slightly to account for the updated text leading

Copy link
Collaborator

@BrunoQuaresma BrunoQuaresma Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it something we could use CSS variables and calc to make the top value more reliable and easier to understand? By understand I mean, why is it 2px? If not, a comment would be nice.

Comment on lines -23 to -29
"& code": {
background: theme.palette.divider,
fontSize: 12,
padding: "2px 4px",
color: theme.palette.text.primary,
borderRadius: 2,
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code seemed to be part of a previous version of the component. None of the styling ever applied to anything

@@ -17,29 +13,14 @@ export const WorkspaceProxyPage: FC = () => {
} = useProxy();

return (
<Section
Copy link
Member Author

@Parkreiner Parkreiner Mar 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was deleted because the header is now located in the view, which I think is how it should've always been

@Parkreiner Parkreiner requested a review from jaaydenh March 13, 2025 20:48
@Parkreiner
Copy link
Member Author

@jaaydenh I'm tagging you for review, but it's not super important that you get to this anytime soon. This is the PR I'm going to be using for the Agentic experiments, and I'm also off tomorrow


interface HeaderProps {
type HeaderHierarchy = "primary" | "secondary";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made it like this so that we can add additional variants over time

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For creating variants, I would recommend you to use class-variance-authority package. You can see how it is used in the Button component.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I've used CVA before – I actually used it in the take-home that got me into Coder. I thought it was a bit too much overhead here, but if we're switching to CVA as a go-to, I can swap that in

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of shadcn, our base components are using CVA so I think it would be nice to use it but it is up to you.

@Parkreiner Parkreiner changed the title fix(site): standardize how headers are displayed for Admin Settings page [DO NOT MERGE] fix(site): standardize headers for Admin Settings page [DO NOT MERGE] Mar 17, 2025

interface HeaderProps {
type HeaderHierarchy = "primary" | "secondary";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For creating variants, I would recommend you to use class-variance-authority package. You can see how it is used in the Button component.

}) => {
const theme = useTheme();

const HeaderTitle = titleHeaderLevel;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing this, we have access to the Slot component from Radix. I think it is a better tool for this kinda of "polymorphic" component.

Copy link
Member Author

@Parkreiner Parkreiner Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if that makes sense here. Slot allows any component to be slotted in as a child – it's too permissive with what it lets you compose into it, when there should only ever be six possible values (h1–h6), and all six have the exact same underlying node type

The current setup is a more restricted form of polymorphism

title: ReactNode;
description?: ReactNode;
secondary?: boolean;
titleVisualHierarchy?: HeaderHierarchy;
titleHeaderLevel?: HeaderLevel;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it is how we did before but since we are touching this, could we also improve the abstraction? I see something like:

<SettingsHeader actions={[<SeeDocsButton />]}>
  <SettingsHeaderTitle>Mytitle</SettingsHeaderTitle>
  <SettingsHeaderSubtitle>Some text hear</SettingsHeaderSubtitle>
</SettingsHeader>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a storybook for it covering the new variants?

@github-actions github-actions bot added the stale This issue is like stale bread. label Mar 27, 2025
@Parkreiner Parkreiner changed the title fix(site): standardize headers for Admin Settings page [DO NOT MERGE] fix(site): standardize headers for Admin Settings page Mar 28, 2025
@Parkreiner Parkreiner removed the stale This issue is like stale bread. label Mar 28, 2025
@Parkreiner
Copy link
Member Author

Parkreiner commented Mar 28, 2025

@BrunoQuaresma Re-requesting your review – I just have some small micro-adjustments to make for three stories. I went ahead and applied your feedback as much as I could – I still feel like bringing in Slot is the wrong move and increases the risks of the component being misused

You'd be a hero if you could get this done today, but if not, I'll go ahead and make a hotfix over the weekend for adjusting the wonky headers that spurred this PR. I just want to make sure we don't ship wonky headers three releases in a row

Comment on lines +78 to +81
// Explicitly not using Radix's Slot component, because we don't want to
// allow any arbitrary element to be composed into this. We specifically
// only want to allow the six HTML headers. Anything else will likely result
// in invalid markup
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment to call out why the code isn't using Slot

Copy link
Collaborator

@BrunoQuaresma BrunoQuaresma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the snapshots look good, go for it!

@Parkreiner Parkreiner merged commit fcac4ab into main Apr 1, 2025
30 checks passed
@Parkreiner Parkreiner deleted the mes/headers-fix-b branch April 1, 2025 14:13
@github-actions github-actions bot locked and limited conversation to collaborators Apr 1, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants