feat(theme): per-theme brand logos (VNClagoon wordmark ↔ SRC mark)
Add optional logoLightUrl/logoDarkUrl to InstalledTheme + resolveThemeLogo() helper; set logos on vnclagoon + src themes; login page and nav-rail prefer the active theme's logo, falling back to the global config logo. So switching theme switches the whole brand. 0 type errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1bc5a6a0ce
commit
88670d4bcf
@@ -1104,6 +1104,8 @@ export const BUILTIN_THEMES: InstalledTheme[] = [
|
||||
description: 'VNClagoon brand theme — deep navy with cyan accent, DM Sans + Syne',
|
||||
css: vnclagoonCSS,
|
||||
skin: vnclagoonSkin,
|
||||
logoLightUrl: '/branding/vncmail-wordmark-on-light.svg',
|
||||
logoDarkUrl: '/branding/vncmail-wordmark-on-dark.svg',
|
||||
variants: ['light', 'dark'],
|
||||
typography: { fontSans: '"DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif' },
|
||||
enabled: true,
|
||||
@@ -1116,6 +1118,8 @@ export const BUILTIN_THEMES: InstalledTheme[] = [
|
||||
author: 'VNC',
|
||||
description: 'SRC Advisory brand theme — Swiss red on white, light-first',
|
||||
css: srcCSS,
|
||||
logoLightUrl: '/branding/src-logo.svg',
|
||||
logoDarkUrl: '/branding/src-logo.svg',
|
||||
variants: ['light', 'dark'],
|
||||
enabled: true,
|
||||
builtIn: true,
|
||||
|
||||
@@ -204,6 +204,13 @@ export interface InstalledTheme {
|
||||
* lifecycle as `css` to keep localStorage small.
|
||||
*/
|
||||
skin?: string;
|
||||
/**
|
||||
* Optional brand logos. When this theme is the active theme, these override
|
||||
* the global login/app logo (a full brand skin, not just colours). Falls back
|
||||
* to the configured global logo when unset.
|
||||
*/
|
||||
logoLightUrl?: string;
|
||||
logoDarkUrl?: string;
|
||||
variants: ThemeVariant[];
|
||||
enabled: boolean;
|
||||
builtIn: boolean;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { InstalledTheme } from './plugin-types';
|
||||
|
||||
/**
|
||||
* Resolve which logo to show. When the active theme carries brand logos
|
||||
* (logoLightUrl/logoDarkUrl), those win — so switching theme switches the whole
|
||||
* brand (VNClagoon wordmark ↔ SRC mark). Otherwise falls back to the globally
|
||||
* configured logo. Returns a raw path; the caller applies withBasePath().
|
||||
*/
|
||||
export function resolveThemeLogo(
|
||||
themes: InstalledTheme[],
|
||||
activeThemeId: string | null,
|
||||
isDark: boolean,
|
||||
fallbackLight: string,
|
||||
fallbackDark: string,
|
||||
): string {
|
||||
const theme = activeThemeId ? themes.find((t) => t.id === activeThemeId) : undefined;
|
||||
if (theme) {
|
||||
const themed = isDark
|
||||
? (theme.logoDarkUrl ?? theme.logoLightUrl)
|
||||
: (theme.logoLightUrl ?? theme.logoDarkUrl);
|
||||
if (themed) return themed;
|
||||
}
|
||||
return isDark ? (fallbackDark || fallbackLight) : (fallbackLight || fallbackDark);
|
||||
}
|
||||
Reference in New Issue
Block a user