Skip to content

Rebrand: sync MUI theme with data-brand in frontend/ entry points#73721

Open
levadadenys wants to merge 3 commits into
denys/re/codeai-color-bridgefrom
denys/re/codeai-mui-theme-brand-sync
Open

Rebrand: sync MUI theme with data-brand in frontend/ entry points#73721
levadadenys wants to merge 3 commits into
denys/re/codeai-color-bridgefrom
denys/re/codeai-mui-theme-brand-sync

Conversation

@levadadenys

Copy link
Copy Markdown
Contributor

What

Follow-up to #73701, closing two findings from its Copilot re-review: frontend/apps/studio/src/routes/__root.tsx and frontend/packages/markdown/demo/main.tsx both load brandOverrides.css, so their CSS tokens correctly flip under ?brand=codeai-next / codeai-audit, but both hardcoded <ThemeProvider theme={CdoTheme}> — so MUI palette-driven components (buttons, etc.) stayed Code.org-purple regardless of the active brand, giving an inconsistent preview for exactly the two surfaces meant to QA the rebrand.

Stacked on #73701 — this branch is based on denys/re/codeai-color-bridge, not staging, since it depends on brandOverrides.css, CodeaiTheme, and CodeaiAuditTheme introduced there. Merge #73701 first.

How

apps/src/util/brand.ts already solves this for the legacy apps/ webpack workspace (getCurrentBrand() / getMuiThemeForBrand()), already used correctly by createReactRoot.tsx and code-studio.js. But frontend/ packages can't import from apps/src/ (separate Turborepo workspace, separate build tooling), and there was no brand-detection code anywhere under frontend/.

Added a getMuiThemeForBrand(brand: string | undefined) export to frontend/packages/component-library/src/themes — already a shared dependency of both apps/ and frontend/ for the theme objects themselves. It takes the raw data-brand attribute value directly (not the BrandCode union type, which frontend/ has no equivalent of) and maps it to CdoTheme / CodeaiTheme / CodeaiAuditTheme.

Wired both entry points to call it with document.documentElement.dataset.brand, computed once (brand doesn't change without a full page reload — matches the existing pattern in createReactRoot.tsx).

Testing

  • New unit tests for getMuiThemeForBrand (6 cases: both real brands, code/codeai/unknown/undefined all fall back to CdoTheme).
  • component-library typecheck + full test suite (348 tests) pass.
  • studio and markdown packages typecheck and build clean with the new import wired in.
  • Manually confirmed via git stash that the one remaining typecheck error in studio (@code-dot-org/music-lab/mocks) is pre-existing and unrelated to this change.

🤖 Generated with Claude Code

frontend/apps/studio/src/routes/__root.tsx and
frontend/packages/markdown/demo/main.tsx both load brandOverrides.css
(codeai-color-bridge) but hardcoded CdoTheme, so MUI palette-driven
components didn't rebrand under codeai-next/codeai-audit even though
CSS tokens did. apps/src/util/brand.ts already solves this for the
legacy apps/ workspace via getCurrentBrand()/getMuiThemeForBrand(), but
frontend/ packages can't import from it, so this adds a
getMuiThemeForBrand(brand) counterpart to component-library/themes
(already a shared dependency of both) and wires both entry points to
it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@levadadenys levadadenys requested a review from a team as a code owner July 8, 2026 15:17

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cdadee2d1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/apps/studio/src/routes/__root.tsx
The /frontend-studio route renders with layout: false, so the bare %html
in frontend_studio/index.html.haml never got the data-brand attribute
that application.html.haml sets. The entry point loads
brandOverrides.css, but without the attribute none of the
[data-brand='codeai-next'] / codeai-audit selectors can activate —
?brand= QA on that shell silently showed legacy colors.

Found by Codex review on PR #73701.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates frontend/ entry points to select the correct MUI theme based on the active data-brand, keeping MUI palette-driven components consistent with the brand-specific CSS token overrides used for rebrand QA surfaces.

Changes:

  • Add getMuiThemeForBrand(brand: string | undefined) to @code-dot-org/component-library/themes, mapping data-brand to CdoTheme / CodeaiTheme / CodeaiAuditTheme.
  • Wire frontend/apps/studio and frontend/packages/markdown demo entry points to use getMuiThemeForBrand(document.documentElement.dataset.brand) instead of hardcoding CdoTheme.
  • Add unit tests and documentation for the new brand→theme selection API.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
frontend/packages/markdown/demo/main.tsx Switch demo ThemeProvider to a brand-selected MUI theme.
frontend/packages/component-library/src/themes/README.md Document how frontend/ entry points should select MUI theme from data-brand.
frontend/packages/component-library/src/themes/index.ts Export the new getMuiThemeForBrand helper from the themes barrel.
frontend/packages/component-library/src/themes/getMuiThemeForBrand.ts Implement brand string → MUI theme mapping.
frontend/packages/component-library/src/themes/tests/getMuiThemeForBrand.test.ts Add unit tests covering supported brands and fallback behavior.
frontend/apps/studio/src/routes/__root.tsx Switch studio root ThemeProvider to a brand-selected MUI theme.

Comment thread frontend/packages/markdown/demo/main.tsx Outdated
The previous guidance — set data-brand in devtools and reload — was
self-defeating: the reload discards the attribute. Read ?brand= from the
URL and stamp it on <html> before theme selection instead, mirroring the
server-side brand router's param.

Found by Copilot review on PR #73721.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@levadadenys levadadenys requested review from a team and lfryemason and removed request for a team July 9, 2026 15:05
Comment on lines +2 to +6
-# data-brand activates the brand-scoped design tokens loaded by this app's
-# entry (component-library-styles/brandOverrides.css); without it,
-# ?brand=codeai-next / codeai-audit QA silently falls back to legacy colors.
-# This shell renders with layout: false, so application.html.haml does not
-# set the attribute for us.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can remove this comment, it's self documenting anyway.

Suggested change
-# data-brand activates the brand-scoped design tokens loaded by this app's
-# entry (component-library-styles/brandOverrides.css); without it,
-# ?brand=codeai-next / codeai-audit QA silently falls back to legacy colors.
-# This shell renders with layout: false, so application.html.haml does not
-# set the attribute for us.

Comment on lines +101 to +103
// data-brand is set server-side via Cdo::Brand before this bundle loads, and
// doesn't change without a full page reload, so it's safe to read once here
// rather than re-resolving per render.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same, we can keep the comments clean, no need to change from before.

Suggested change
// data-brand is set server-side via Cdo::Brand before this bundle loads, and
// doesn't change without a full page reload, so it's safe to read once here
// rather than re-resolving per render.
/** Root layout: applies the CDO MUI theme and Bootstrap providers to all routes. */


`CodeaiTheme` and `CodeaiAuditTheme` inherit all typography and component style overrides from `CdoTheme` via `createTheme(CdoTheme, { palette: ... })`. Only the palette differs.

Entry points under `frontend/` (which cannot import `apps/src/util/brand.ts`) select the MUI theme with `getMuiThemeForBrand(document.documentElement.dataset.brand)`, exported from this package. Every entry point that loads `brandOverrides.css` should also call this, so CSS tokens and MUI palette-driven components stay in sync under the same brand — see `frontend/apps/studio/src/routes/__root.tsx` and `frontend/packages/markdown/demo/main.tsx`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let me add a core package utility that represents what "brand" we're on. #73721 - this will be a followup and non-blocking.

Comment on lines 1 to 3
export {default as CdoTheme} from './code.org';
export {default as CodeaiTheme} from './codeai';
export {default as CodeaiAuditTheme} from './codeai-audit';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we want to prevent individual usages of specific themes and route all requests to getMuiThemeForBrand? If so, we can remove the exports or add an eslint rule for restricted imports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants