diff --git a/packages/core/src/node/plugins/index.ts b/packages/core/src/node/plugins/index.ts index 0d3b4f5cf..044827638 100644 --- a/packages/core/src/node/plugins/index.ts +++ b/packages/core/src/node/plugins/index.ts @@ -15,6 +15,19 @@ export interface DevToolsOptions { */ builtinDevTools?: boolean + /** + * Override the branding handed to the DevTools client (`@devframes/hub-ui`) + * — product name, logo, wordmark, primary color, tagline, favicon, and + * window title. + * + * Each field is merged over the built-in Vite DevTools defaults, so a host + * embedding Vite DevTools (e.g. Nuxt DevTools) can re-skin the client while + * inheriting any field it leaves unset. Asset fields + * (`logo`/`wordmark`/`favicon`) take URL strings the host is responsible for + * serving. + */ + branding?: ViteDevToolsUiOptions['branding'] + /** * How the embedded floating dock reveals itself on a fresh page. * @@ -63,11 +76,12 @@ export async function DevTools(options: DevToolsOptions = {}): Promise const { builtinDevTools = true, build, + branding, embeddedVisibility = 'normal', dockPreferences, } = options - const ui = { embeddedVisibility, dockPreferences } + const ui = { branding, embeddedVisibility, dockPreferences } const plugins = [ DevToolsInjection(), diff --git a/packages/core/src/node/ui.ts b/packages/core/src/node/ui.ts index 6b5b113df..f7dd7f597 100644 --- a/packages/core/src/node/ui.ts +++ b/packages/core/src/node/ui.ts @@ -4,6 +4,18 @@ import { createUi } from '@devframes/hub-ui' import { DEVTOOLS_ASSETS_BASE } from '../dirs' export interface ViteDevToolsUiOptions { + /** + * Override the Vite DevTools branding handed to `@devframes/hub-ui` + * (`ConnectionMeta.configs.ui.branding`) — product name, logo, wordmark, + * primary color, tagline, favicon, and window title. + * + * Each field is merged over the built-in Vite DevTools defaults + * ({@link viteDevToolsBranding}), so a host such as Nuxt DevTools can + * re-skin the client while inheriting any field it leaves unset. Asset + * fields (`logo`/`wordmark`/`favicon`) take URL strings; a host serving its + * own marks is responsible for hosting them. + */ + branding?: DevframeBranding /** * How the embedded floating dock reveals itself on a fresh page. Seeds a * user-overridable preference published as @@ -41,11 +53,34 @@ export function viteDevToolsBranding(): DevframeBranding { * that serves the DevTools client. Hands the reference viewer + embedded * bootstrap to `initHub({ ui })` (dev serve) or is copied out by the static * build. + * + * A host embedding Vite DevTools (e.g. Nuxt DevTools) can re-skin the client + * via `options.branding`, which is shallow-merged field-by-field over the + * built-in {@link viteDevToolsBranding} defaults. */ export function createViteDevToolsUi(options: ViteDevToolsUiOptions = {}): DevframeHubUi { return createUi({ - branding: viteDevToolsBranding(), + branding: resolveBranding(options.branding), embeddedVisibility: options.embeddedVisibility, dockPreferences: options.dockPreferences, }) } + +/** + * Merge a host's branding overrides over the Vite DevTools defaults. Only keys + * the host actually sets win; an explicit `undefined` is ignored so a partial + * override never clobbers a default with a hole. + */ +function resolveBranding(overrides?: DevframeBranding): DevframeBranding { + const branding = viteDevToolsBranding() + if (!overrides) { + return branding + } + for (const key of Object.keys(overrides) as (keyof DevframeBranding)[]) { + const value = overrides[key] + if (value !== undefined) { + branding[key] = value as never + } + } + return branding +}