Repository navigation
feat(branding): multi-tenant org branding (logo, name, colours) with validation and AA contrast - #1653
Merged
Wilfred007 merged 2 commits intoSep 27, 2026
Conversation
Add utils/brand.ts (hex validation/normalisation, WCAG contrast ratio, readable text picker, https/raster-only logo sanitiser, org-name sanitiser). ThemeProvider now only writes valid hex colours into the --brand-* custom properties and sets --brand-on-primary to white or navy, whichever keeps AA contrast on the org's primary colour.
- BrandingSettings (Settings page): organization name, https logo URL, primary and accent colour (picker + hex input), live preview with the button-text contrast ratio, inline validation (role=alert, aria-invalid), save with a polite status message, and reset to PayD defaults. - BrandLogo in AppLayout's header shows the org logo and/or name when configured (falls back to the PayD wordmark, and on logo load errors). - Tests cover save/theme, invalid-logo blocking and reset.
|
@onejasonn Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Organizations can now configure a custom logo, name, primary colour and accent colour that theme their PayD portal.
ThemeProvideralready stored anOrgBrandConfigand mapped it to--brand-*CSS tokens, but nothing let an org set it,logoUrlwas never rendered, and brand values were written into CSS unvalidated. This PR closes those gaps.Changes
1. Validation and contrast (
src/utils/brand.ts,ThemeProvider)#rgbor#rrggbb, normalised) are written into--brand-primary,--brand-accentand--brand-header-bg. Anything else, such asred; background:url(x), is ignored and the default myworkpay-inspired tokens apply.--brand-on-primarytoken is set to white or deep navy (#0b1b3a), whichever gives the higher WCAG contrast on the org's primary colour. Text on a brand fill stays readable whatever colour an org picks.https:and rasterdata:image/(png|jpeg|gif|webp)URIs are accepted.javascript:,http:(mixed content) and SVG data URIs are rejected.2. Settings UI (
src/components/BrandingSettings.tsx, inSettings)<label>aria-invalidand arole="alert"message, and Save is disabledrole="status"focus-visibleringsmd. Uses the existingcard glass,--surface-hiand--border-hitokens, so it follows light and dark mode.3. Branded header (
src/components/BrandLogo.tsx, used inAppLayout)alt="<Org> logo") and/or name when configured, with the name truncated on narrow screens. A screen-reader-only ", powered by PayD" is included.onError).Tests
utils/__tests__/brand.test.ts:__tests__/ThemeProvider.test.tsx:--brand-on-primarycomponents/__tests__/BrandingSettings.test.tsx:Closes Add multi-tenant branding support #1505
Closes Complete i18n coverage audit for en/es locales #1506
Closes Add a global search component with cmd+k shortcut #1503
Closes Redesign organization/billing/security settings pages #1504
These weren't run locally because there's no
node_modulesin my checkout, so vitest will run them in CI.Notes
payd-org-brandstorage used byThemeProvider. When an org-settings API endpoint exists, the samesetBrandConfigcall can be fed from it so the branding follows the organization across devices.Commits
feat(branding): validate org brand values and keep AA contrastfeat(branding): org branding settings and branded header logo