Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions packages/hub-ui/src/client/dock-preferences.ts

This file was deleted.

20 changes: 1 addition & 19 deletions packages/hub-ui/src/client/embedded/visibility.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,6 @@
import type { EmbeddedVisibility } from '../../types'
import { HUB_UI_HIDE_EVENT } from '../constants'

/**
* How the embedded floating dock reveals itself on a fresh page — the
* reference UI's port of Nuxt DevTools' opt-in overlay, published as
* `ConnectionMeta.configs.ui.embeddedVisibility` and set via
* `createUi({ embeddedVisibility })`.
*
* - `normal` (default) — the dock is shown immediately.
* - `passive` — the dock starts hidden and a console hint offers the reveal
* shortcut; revealing persists per-origin, so later sessions on this
* browser start shown. The "Hide" command returns to passive.
* - `hidden` — the dock starts hidden and the shortcut reveals it for the
* current session only; nothing is persisted.
*
* Whatever the policy, the reveal state is a user-overridable preference —
* the same shape as the float/edge dock mode: the config seeds it, the
* visitor's own reveal/hide wins from then on.
*/
export type EmbeddedVisibility = 'normal' | 'passive' | 'hidden'

/** Per-origin persisted reveal flag for `passive` mode. */
const REVEAL_STORAGE_KEY = 'devframes-dock-revealed'

Expand Down
34 changes: 1 addition & 33 deletions packages/hub-ui/src/client/state/branding.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,8 @@
import type { Ref } from 'vue'
import type { BrandingLogo, DevframeBranding } from '../../types'
import { computed, ref } from 'vue'
import { isDark } from './color-mode'

/**
* A logo asset — a single URL/data-URI, or per-color-scheme variants. The dark
* variant falls back to the light one when only `light` is given (or a bare
* string is used for both).
*/
export type BrandingLogo = string | { light: string, dark: string }

/**
* Consumer-facing branding for the reference hub-ui. Every field is optional
* and falls back to devframe's own identity. Published as
* `ConnectionMeta.configs.ui.branding` via `createUi({ branding })`, and
* read from the one connection handshake the dock already performs —
* `ConnectionMeta` has its own cross-realm propagation (see
* `DEVFRAME_CONNECTION_KEY`), so branding needs no globals or query params
* of its own.
*/
export interface DevframeBranding {
/** Product name — the wordmark, window titles, and all user-visible copy. */
productName?: string
/** Logo mark (URL / data-URI), rendered via `<img>`. */
logo?: BrandingLogo
/** Optional standalone wordmark image; when absent, mark + productName text is composed. */
wordmark?: BrandingLogo
/** Brand color; feeds `--devframe-primary` and the whole primary ramp. */
primaryColor?: string
/** Short line for the auth screen and the standalone meta description. */
tagline?: string
/** Favicon URL — applied on the standalone viewer and the popped-out window only. */
favicon?: string
/** Window/tab title; defaults to `productName`. */
windowTitle?: string
}

/** Branding with defaults resolved — what the UI actually renders. */
export interface ResolvedBranding {
productName: string
Expand Down
8 changes: 2 additions & 6 deletions packages/hub-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import type { DevframeHubUi } from '@devframes/hub/initiate'
import type { DevframeDockPreferences } from './client/dock-preferences'
import type { EmbeddedVisibility } from './client/embedded/visibility'
import type { DevframeBranding } from './client/state/branding'
import type { DevframeBranding, DevframeDockPreferences, EmbeddedVisibility } from './types'
import { existsSync } from 'node:fs'
import { join } from 'node:path'
import { fileURLToPath } from 'node:url'

export type { DevframeDockPreferences } from './client/dock-preferences'
export type { EmbeddedVisibility } from './client/embedded/visibility'
export type { DevframeBranding } from './client/state/branding'
export type { DevframeBranding, DevframeDockPreferences, EmbeddedVisibility } from './types'

declare module 'devframe/types' {
interface DevframeConnectionConfigsRegistry {
Expand Down
86 changes: 86 additions & 0 deletions packages/hub-ui/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Published `createUi()` config types, kept framework-free so the node
* entry's declaration rollup (`dist/index.d.mts`) never pulls in Vue's type
* surface. Client modules that need these types import them *from* here
* (never the reverse) — see `client/state/branding.ts`,
* `client/embedded/visibility.ts`.
*/

/**
* A logo asset — a single URL/data-URI, or per-color-scheme variants. The dark
* variant falls back to the light one when only `light` is given (or a bare
* string is used for both).
*/
export type BrandingLogo = string | { light: string, dark: string }

/**
* Consumer-facing branding for the reference hub-ui. Every field is optional
* and falls back to devframe's own identity. Published as
* `ConnectionMeta.configs.ui.branding` via `createUi({ branding })`, and
* read from the one connection handshake the dock already performs —
* `ConnectionMeta` has its own cross-realm propagation (see
* `DEVFRAME_CONNECTION_KEY`), so branding needs no globals or query params
* of its own.
*/
export interface DevframeBranding {
/** Product name — the wordmark, window titles, and all user-visible copy. */
productName?: string
/** Logo mark (URL / data-URI), rendered via `<img>`. */
logo?: BrandingLogo
/** Optional standalone wordmark image; when absent, mark + productName text is composed. */
wordmark?: BrandingLogo
/** Brand color; feeds `--devframe-primary` and the whole primary ramp. */
primaryColor?: string
/** Short line for the auth screen and the standalone meta description. */
tagline?: string
/** Favicon URL — applied on the standalone viewer and the popped-out window only. */
favicon?: string
/** Window/tab title; defaults to `productName`. */
windowTitle?: string
}

/**
* The reference UI's dock-bar rendering preferences, set via
* `createUi({ dockPreferences })` and published as
* `ConnectionMeta.configs.ui.dockPreferences`. Read by the embedded dock and
* the standalone viewer at boot.
*
* Like the float/edge dock mode, these seed user-overridable state — the
* config sets the default, the visitor's own choice wins from then on.
*/
export interface DevframeDockPreferences {
/**
* The top-level dock-bar **category** ordering — a map of category id →
* ordering weight (lower sorts earlier), merged beneath
* `DEFAULT_CATEGORIES_ORDER`.
*/
categoryOrder?: Record<string, number>
/**
* Preferred inline-item capacity for the floating dock bar before entries
* overflow. Edge mode ignores it — it shows every entry with no cutoff.
*/
maxVisibleItems?: number
/** Seeds a first-run visitor's dock mode (float vs edge). */
defaultMode?: 'float' | 'edge'
/** Seeds a first-run visitor's dock position. */
defaultPosition?: 'left' | 'right' | 'top' | 'bottom'
}

/**
* How the embedded floating dock reveals itself on a fresh page — the
* reference UI's port of Nuxt DevTools' opt-in overlay, published as
* `ConnectionMeta.configs.ui.embeddedVisibility` and set via
* `createUi({ embeddedVisibility })`.
*
* - `normal` (default) — the dock is shown immediately.
* - `passive` — the dock starts hidden and a console hint offers the reveal
* shortcut; revealing persists per-origin, so later sessions on this
* browser start shown. The "Hide" command returns to passive.
* - `hidden` — the dock starts hidden and the shortcut reveals it for the
* current session only; nothing is persisted.
*
* Whatever the policy, the reveal state is a user-overridable preference —
* the same shape as the float/edge dock mode: the config seeds it, the
* visitor's own reveal/hide wins from then on.
*/
export type EmbeddedVisibility = 'normal' | 'passive' | 'hidden'
8 changes: 8 additions & 0 deletions plugins/messages/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ export default defineConfig([
clean: false,
platform: 'neutral',
tsconfig,
// `client/index.ts` re-exports `useMessages(): Reactive<MessagesState>` —
// a genuine Vue reactivity type, not just a documentation import. Without
// this, the dts bundler inlines Vue's entire runtime-core/reactivity type
// surface to describe `Reactive<T>` (≈935 KB); `neverBundle` keeps the
// reference as `import('vue').Reactive<...>` instead. This build is
// `emitDtsOnly`, so it has no effect on the JS output (built separately
// by the Vite lib build for the client, and by the node build above).
deps: { neverBundle: ['vue'] },
dts: { emitDtsOnly: true },
outExtensions: () => ({ dts: '.d.mts' }),
entry: { ...clientEntries, ...serverEntries },
Expand Down
Loading