* Creates a reactive pending-state map and a run() helper for async actions with toast notifications.
*
* Encapsulates the pending-key guard, toast feedback, and error logging pattern
- * shared by modern skin components.
+ * shared across layout composables.
* @param initialPending - Object defining the pending keys (e.g. `{ connection: false, startStop: false }`)
* @param onRefresh - Called after each successful action (e.g. `() => emit('need-refresh')`)
* @returns `{ pending, run }` — reactive pending map and action executor
}
const lockConnector = (): void => {
+ // 'lock' key is shared by lockConnector and unlockConnector
run('lock', {
action: () => $uiClient.lockConnector(hashId.value, connectorId.value),
errorMsg: 'Error locking connector',
/**
* Extracts the common data-fetching and WebSocket lifecycle logic shared by layout components.
*
- * Registers `onMounted` / `onUnmounted` hooks internally so consumers do not need to.
+ * Registers `onMounted` / `onUnmounted` hooks internally. Also exposes
+ * `registerWSEventListeners` / `unregisterWSEventListeners` for manual lifecycle management.
* @returns Layout data state and control functions
*/
export function useLayoutData (): LayoutData {
return isValidSkin(stored) ? stored : DEFAULT_SKIN
})()
)
-// JS/testing hook — no CSS uses [data-skin]; skin isolation is via component class scoping.
+// Sets data-skin on document root for CSS scoping (used by modern skin) and JS/testing hooks.
if (typeof document !== 'undefined') {
document.documentElement.setAttribute('data-skin', activeSkinId.value)
}
/**
* CSS token contract.
*
- * Typography and spacing tokens are provided by `base.css` (shared across all themes).
- * Color tokens (`color-*`) and `color-scheme` must be defined per theme file.
+ * Typography and spacing tokens have defaults in `base.css` and may be overridden per theme.
+ * Color tokens (`color-*`) have no defaults and MUST be defined per theme file.
* When adding a new theme, ensure all `color-*` tokens below are defined in your theme CSS.
*
* Every theme file MUST define a value for each token (as `--{token-name}`).
/* Modern skin styles.
*
* Flat, modern design with Material-inspired structural patterns.
- * - Teal primary (Material 500/400) + Green / Amber / Red state colours
+ * - Primary and state colours driven by the active theme contract
* - Onest across the UI; mono only for the supervision URL itself
* - Elevation tiers: base < card body < raised (header/modal) + sunken inserts
* - Hovers only touch colour / shadow, never layout
* Single source of truth for available skins.
* Each skin carries metadata and a lazy CSS loader for code splitting.
*
- * Convention: All skin CSS MUST scope rules to `html[data-skin='<id>']` to prevent
- * style bleeding when multiple skin stylesheets are loaded in the DOM simultaneously.
+ * Convention: Skin CSS should scope structural rules to `html[data-skin='<id>']` or use
+ * component-scoped class prefixes (e.g. `.classic-*`, `.modern-*`) to prevent style bleeding.
*/
import type { Component } from 'vue'