From: Jérôme Benoit Date: Thu, 30 Apr 2026 09:15:56 +0000 (+0200) Subject: fix(ui-web): future-proof light-mode pill overrides and fix import ordering X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=147e9f441aa50f5db9b672d3a9863c10d23a2a0e;p=e-mobility-charging-stations-simulator.git fix(ui-web): future-proof light-mode pill overrides and fix import ordering --- diff --git a/ui/web/src/core/index.ts b/ui/web/src/core/index.ts index 231af0bf..6fcd1353 100644 --- a/ui/web/src/core/index.ts +++ b/ui/web/src/core/index.ts @@ -23,6 +23,7 @@ export { useUIClient, } from './providers.js' export { + deleteFromLocalStorage, deleteLocalStorageByKeyPattern, getFromLocalStorage, getLocalStorage, diff --git a/ui/web/src/shared/composables/useTheme.ts b/ui/web/src/shared/composables/useTheme.ts index 9f399956..e460ac8a 100644 --- a/ui/web/src/shared/composables/useTheme.ts +++ b/ui/web/src/shared/composables/useTheme.ts @@ -8,6 +8,17 @@ export const AVAILABLE_THEMES = THEME_IDS export const DEFAULT_THEME: ThemeName = 'tokyo-night-storm' export const THEME_STORAGE_KEY = 'ecs-ui-theme' +const THEME_COLOR_SCHEME: Record = { + 'catppuccin-latte': 'light', + dracula: 'dark', + 'gruvbox-dark': 'dark', + 'rose-pine': 'dark', + 'sap-horizon': 'light', + 'teal-dark': 'dark', + 'teal-light': 'light', + 'tokyo-night-storm': 'dark', +} + export type ThemeName = (typeof THEME_IDS)[number] /** @@ -29,9 +40,8 @@ const activeThemeId: Ref = ref( const lastError: Ref = ref(null) /** - * Applies a theme by setting the data-theme attribute on the document root. + * Applies a theme by setting data-theme and data-color-scheme attributes on the document root. * Disables CSS transitions during the swap to prevent color flash (VueUse pattern). - * The color-scheme is handled by CSS [data-theme] declarations. * @param themeName - The theme name to apply */ function applyTheme (themeName: ThemeName): void { @@ -39,6 +49,7 @@ function applyTheme (themeName: ThemeName): void { // Disable CSS transitions during theme swap to prevent color flash (VueUse pattern). document.documentElement.classList.add('theme-switching') document.documentElement.setAttribute('data-theme', themeName) + document.documentElement.setAttribute('data-color-scheme', THEME_COLOR_SCHEME[themeName]) // Force reflow so browsers apply the transition-disable before restoring transitions. // eslint-disable-next-line no-void void document.documentElement.offsetHeight diff --git a/ui/web/src/skins/modern/ModernLayout.vue b/ui/web/src/skins/modern/ModernLayout.vue index 0fce3967..76ef9a7d 100644 --- a/ui/web/src/skins/modern/ModernLayout.vue +++ b/ui/web/src/skins/modern/ModernLayout.vue @@ -92,6 +92,8 @@ import { useLayoutData } from '@/shared/composables/useLayoutData.js' import { useSimulatorControl } from '@/shared/composables/useSimulatorControl.js' import ConfirmDialog from './components/ConfirmDialog.vue' +import SimulatorBar from './components/SimulatorBar.vue' +import StationCard from './components/StationCard.vue' /** * Creates a lazy-loaded dialog component with shared loading/error boundaries. @@ -118,8 +120,6 @@ const SetSupervisionUrlDialog = defineAsyncDialog( const StartTransactionDialog = defineAsyncDialog( () => import('./components/dialogs/StartTransactionDialog.vue') ) -import SimulatorBar from './components/SimulatorBar.vue' -import StationCard from './components/StationCard.vue' const $chargingStations = useChargingStations() diff --git a/ui/web/src/skins/modern/modern.css b/ui/web/src/skins/modern/modern.css index a869cda3..7fa6eb6f 100644 --- a/ui/web/src/skins/modern/modern.css +++ b/ui/web/src/skins/modern/modern.css @@ -855,25 +855,19 @@ html[data-skin='modern'] #app { /* Light-theme pill overrides — state colours are already dark (Material 700) * and readable on light backgrounds without white mixing. */ -:root[data-theme='catppuccin-latte'] .modern-pill--ok, -:root[data-theme='sap-horizon'] .modern-pill--ok, -:root[data-theme='teal-light'] .modern-pill--ok { +:root[data-color-scheme='light'] .modern-pill--ok { color: var(--color-state-ok); background-color: color-mix(in srgb, var(--color-state-ok) 14%, transparent); border-color: color-mix(in srgb, var(--color-state-ok) 35%, transparent); } -:root[data-theme='catppuccin-latte'] .modern-pill--warn, -:root[data-theme='sap-horizon'] .modern-pill--warn, -:root[data-theme='teal-light'] .modern-pill--warn { +:root[data-color-scheme='light'] .modern-pill--warn { color: var(--color-state-warn); background-color: color-mix(in srgb, var(--color-state-warn) 18%, transparent); border-color: color-mix(in srgb, var(--color-state-warn) 50%, transparent); } -:root[data-theme='catppuccin-latte'] .modern-pill--err, -:root[data-theme='sap-horizon'] .modern-pill--err, -:root[data-theme='teal-light'] .modern-pill--err { +:root[data-color-scheme='light'] .modern-pill--err { color: var(--color-state-err); background-color: color-mix(in srgb, var(--color-state-err) 14%, transparent); border-color: color-mix(in srgb, var(--color-state-err) 35%, transparent); diff --git a/ui/web/tests/unit/Utils.test.ts b/ui/web/tests/unit/Utils.test.ts index d7149271..d334cbca 100644 --- a/ui/web/tests/unit/Utils.test.ts +++ b/ui/web/tests/unit/Utils.test.ts @@ -7,6 +7,7 @@ import { ResponseStatus } from 'ui-common' import { afterEach, describe, expect, it, vi } from 'vitest' import { + deleteFromLocalStorage, getFromLocalStorage, getLocalStorage, resetToggleButtonState, @@ -15,7 +16,6 @@ import { useConfiguration, useTemplates, } from '@/core/index.js' -import { deleteFromLocalStorage } from '@/core/storage.js' import { useFetchData } from '@/shared/composables/useFetchData.js' import { toastMock } from '../setup.js'