Currently applied theme ID (synchronous access)
Observable for the actually applied theme (resolved theme ID)
All registered themes, for UI consumption (e.g. theme picker menus)
The active org brand overlay id, or null if none is applied.
Whether the service has been initialized
Current theme preference (synchronous access)
Observable for user's theme preference (theme ID or 'system')
Reactive list of the user's starred brand theme ids.
Emits after any saved-theme mutation so open dashboards can refresh their lists.
Apply an org brand overlay **independently of the user's light/dark mode. The overlay layers under whatever base theme is active and is re-asserted whenever the user toggles light/dark. Persists the id to localStorage so the pre-paint script restores the attribute on next load.
id of a brand theme registered via RegisterBrandTheme.
Optionaloptions: { persist?: boolean }Optionalpersist?: booleanpass false for session-only overlays backed by Blob URLs
(e.g. Theme Studio's draft workspace preview) — a Blob URL doesn't survive a
reload, so persisting its id would leave the pre-paint script pointing at a
dangling overlay and clobber the user's real persisted selection. Defaults true.
Remove the active org brand overlay (revert to the base MJ tokens).
The brand theme the user last applied (or null to follow the org default).
The user's starred brand theme ids (synchronous).
Look up a theme definition by ID. Returns undefined if the theme ID is not registered.
Initialize the theme service. Call after login when UserInfoEngine is available.
Whether a theme id is starred by the user.
Broadcast that the set of saved themes changed (create/rename/delete/duplicate/default).
Register a brand theme from its seeds.
Derives the full --mj-* token contract with @memberjunction/theme-engine, emits
the [data-theme-overlay="<id>"] CSS, and publishes it as a session-scoped Blob
URL that plugs into the existing CssUrl overlay path — so brand themes apply
through the same machinery as file-based custom themes. Returns the derived
theme so callers can surface the a11y contrast report / previews.
The emitted overlay overrides only the primitive ramps (plus viz/shadow/font/
radius); every semantic token and the [data-theme="dark"] block reference those
primitives, so both light and dark re-point automatically off one block.
OptionalbaseTheme?: "light" | "dark"OptionalcustomCss?: string | nullAdvanced: raw CSS appended to the overlay, auto-scoped to this theme.
Optionaldescription?: stringOptionallogos?: ThemeLogosOptional logo variant URLs + geometry, emitted as --mj-logo-*.
Optionaloverrides?: string | Record<string, string> | nullAdvanced: per-token overrides (JSON map or object) merged over the derived vars.
ThemeSeeds object or the entity's Seeds JSON string.
Register a custom theme. If a theme with the same ID already exists, it is replaced (allowing override of built-in themes if desired).
Reset the service (call on logout)
Persist (or clear, with null) the user's chosen brand theme so login restores it.
Set the theme preference and apply it.
A registered theme ID or 'system'
Toggle a theme's starred state and persist to User Settings.
the new starred state (true = now starred).
Service to manage application themes with pluggable custom theme support.
Built-in themes (light/dark) work identically to before. Custom themes inherit from a base theme and overlay additional CSS token overrides via a dynamically loaded stylesheet.
CSS resolution for custom themes (e.g. "Izzy Dark" extending dark):
:rootlight defaults (from _tokens.scss in this package)[data-theme="dark"]dark overrides (from _tokens.scss in this package)[data-theme-overlay="izzy-dark"]custom overrides (loaded dynamically)Follows the DeveloperModeService pattern: