Skip to content

feat(branding): introduce support for icon-only branding and better flexibility - #428

Open
govindavashishtha wants to merge 4 commits into
mainfrom
chore/gv/width-logo
Open

feat(branding): introduce support for icon-only branding and better flexibility#428
govindavashishtha wants to merge 4 commits into
mainfrom
chore/gv/width-logo

Conversation

@govindavashishtha

@govindavashishtha govindavashishtha commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add theme.brand.mode so hosts pick chrome look first: icon-title | icon-only | logo (omit brand for default TrueForge marks).
  • BrandConfig is a discriminated union on mode. name is required and always labels the mark (alt / aria-label); visible title text only for icon-title.
  • Compact surfaces always use the square icon. Expanded chrome uses logo when mode: 'logo', otherwise icon (+ title when icon-title).
  • resolveBrandChrome() maps mode{ expandedVariant, collapsedVariant, showTitle }; SidebarLayout uses it instead of field heuristics.
  • Docs, changelog, and tests updated for the new contract.

Contract

brand.mode Required Expanded Collapsed
omit brand TF wordmark TF square
'icon-title' name (+ optional icon) square + title square
'icon-only' name, icon square (alt only) square
'logo' name, icon, logo wide logo (alt only) square

Usage

// Default TrueForge wordmark / square mark
<TrueForgeUI server={server} layout="sidebar" />

// Icon + title
theme={{ brand: { mode: 'icon-title', name: 'Acme', icon: '/icon.svg' } }}

// Icon only (name kept for alt)
theme={{ brand: { mode: 'icon-only', name: 'Acme', icon: '/icon.svg' } }}

// Wide logo when expanded
theme={{
  brand: {
    mode: 'logo',
    name: 'Acme',
    icon: '/icon.svg',
    logo: '/wordmark.svg',
    href: '/',
  },
}}

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Breaking change to `theme.brand` shape affects all customized branding; behavior is localized to theme/layout chrome, not auth or data paths.
> 
> **Overview**
> Introduces **`theme.brand.mode`** (`icon-title` | `icon-only` | `logo`) so hosts choose header chrome up front. **`BrandConfig`** is now a discriminated union: square **`icon`**, optional wide **`logo`**, required **`name`** (always for a11y; visible title text only for `icon-title`). **`href`** moves to the brand object (off per-image config).
> 
> **`BrandLogo`** gains **`variant="icon" | "logo"`**; when `brand` is omitted, expanded surfaces show a built-in TrueForge **wordmark** SVG and compact surfaces keep the square mark. **`resolveBrandChrome()`** is exported and **`SidebarLayout`** uses it for expanded/collapsed variants and title visibility (widget FAB / welcome use `variant="icon"`).
> 
> Docs, README, changelog, and tests reflect the new contract. **Migration:** replace `brand: { name, logo }` with the appropriate `mode` plus `icon` / `logo` fields.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3ed36defb76ac9ca322aa8d2703f5b70a901505c. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

… logo configurations

- Added new  type to support square icons and optional wide logos.
- Updated theme documentation to reflect changes in branding options.
- Implemented logic for rendering icons and logos based on the theme mode.
- Introduced fallback mechanisms for compact and expanded surfaces.
- Updated examples and tests to demonstrate new branding capabilities.
@changeset-bot

changeset-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3ed36de

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@truefoundry/trueforge-ui Minor
@truefoundry/trueforge Patch
frontend Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment thread packages/trueforge-ui/src/theme/brand.tsx
@govindavashishtha
govindavashishtha enabled auto-merge (squash) August 25, 2026 08:00
@govindavashishtha govindavashishtha self-assigned this Aug 25, 2026

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cbc4d79. Configure here.

Comment thread packages/trueforge-ui/src/theme/brand.tsx
govindavashishtha and others added 2 commits August 26, 2026 19:18
Hosts pick icon-title, icon-only, or logo first; name always labels the mark, and resolveBrandChrome drives sidebar chrome.

Co-authored-by: Cursor <cursoragent@cursor.com>
<span className="truncate text-lg font-semibold tracking-tight">{brandName}</span>
<BrandLogo
variant={chrome.expandedVariant}
className={cn('h-5 max-w-40 shrink-0 object-contain', chrome.expandedVariant === 'icon' && 'w-5')}

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.

can we extract this out in a separate constant and reuse it ?
As the same class is being used above

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants