feat: Add richer card theme support (#1809)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { StyleManager } from '../../src/card-controller/style-manager';
|
||||
import { FrigateCardView } from '../../src/config/types';
|
||||
import { createCardAPI, createConfig, createHASS, createView } from '../test-utils';
|
||||
import { FrigateCardView, ThemeName } from '../../src/config/types';
|
||||
import { createCardAPI, createConfig, createView } from '../test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('StyleManager', () => {
|
||||
@@ -9,97 +9,45 @@ describe('StyleManager', () => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('setLightOrDarkMode', () => {
|
||||
it('dark mode unspecified', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setLightOrDarkMode();
|
||||
|
||||
expect(element.getAttribute('dark')).toBeNull();
|
||||
});
|
||||
|
||||
it('dark mode explicitly off', () => {
|
||||
describe('should set dimmable', () => {
|
||||
it('should be dimmable when dim is true', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
dark_mode: 'off',
|
||||
dim: true,
|
||||
},
|
||||
}),
|
||||
);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setLightOrDarkMode();
|
||||
manager.updateFromConfig();
|
||||
|
||||
expect(element.getAttribute('dark')).toBeNull();
|
||||
expect(element.getAttribute('dimmable')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('dark mode explicitly set', () => {
|
||||
it('should not be dimmable when dim is false', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
dark_mode: 'on',
|
||||
dim: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setLightOrDarkMode();
|
||||
manager.updateFromConfig();
|
||||
|
||||
expect(element.getAttribute('dark')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('dark mode auto without interaction', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
dark_mode: 'auto',
|
||||
},
|
||||
}),
|
||||
);
|
||||
vi.mocked(api.getInteractionManager().hasInteraction).mockReturnValue(false);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setLightOrDarkMode();
|
||||
|
||||
expect(element.getAttribute('dark')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('dark mode auto with HA dark mode', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
dark_mode: 'auto',
|
||||
},
|
||||
}),
|
||||
);
|
||||
vi.mocked(api.getInteractionManager().hasInteraction).mockReturnValue(true);
|
||||
const hass = createHASS();
|
||||
hass.themes.darkMode = true;
|
||||
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(hass);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setLightOrDarkMode();
|
||||
|
||||
expect(element.getAttribute('dark')).not.toBeNull();
|
||||
expect(element.getAttribute('dimmable')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('setExpandedMode', () => {
|
||||
describe('should set expanded mode', () => {
|
||||
it('with no view or known media', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
@@ -189,14 +137,14 @@ describe('StyleManager', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setMinMaxHeight', () => {
|
||||
describe('should set min and max height', () => {
|
||||
it('without a config', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setMinMaxHeight();
|
||||
manager.updateFromConfig();
|
||||
|
||||
expect(element.style.getPropertyValue('--frigate-card-max-height')).toBeFalsy();
|
||||
expect(element.style.getPropertyValue('--frigate-card-expand-height')).toBeFalsy();
|
||||
@@ -215,13 +163,13 @@ describe('StyleManager', () => {
|
||||
);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setMinMaxHeight();
|
||||
manager.updateFromConfig();
|
||||
|
||||
expect(element.style.getPropertyValue('--frigate-card-height')).toBe('800px');
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPerformance', () => {
|
||||
describe('should set performance', () => {
|
||||
it('no styles set', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
@@ -229,7 +177,7 @@ describe('StyleManager', () => {
|
||||
vi.mocked(api.getConfigManager().getCardWideConfig).mockReturnValue({});
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setPerformance();
|
||||
manager.updateFromConfig();
|
||||
|
||||
expect(
|
||||
element.style.getPropertyValue('--frigate-card-css-box-shadow'),
|
||||
@@ -255,7 +203,7 @@ describe('StyleManager', () => {
|
||||
);
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.setPerformance();
|
||||
manager.updateFromConfig();
|
||||
|
||||
expect(element.style.getPropertyValue('--frigate-card-css-box-shadow')).toEqual(
|
||||
'none',
|
||||
@@ -411,4 +359,111 @@ describe('StyleManager', () => {
|
||||
expect(manager.getAspectRatioStyle()).toEqual({ 'aspect-ratio': '4 / 3' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('should apply themes', () => {
|
||||
it('should not apply themes without a config', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.applyTheme();
|
||||
|
||||
expect(element.getAttribute('themes')).toBeNull();
|
||||
});
|
||||
|
||||
describe('should apply named theme', () => {
|
||||
it.each([
|
||||
['light' as const],
|
||||
['dark' as const],
|
||||
['traditional' as const],
|
||||
['ha' as const],
|
||||
])('%s', (theme: ThemeName) => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
theme: {
|
||||
themes: [theme],
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.applyTheme();
|
||||
|
||||
expect(element.getAttribute('themes')).toBe(theme);
|
||||
});
|
||||
});
|
||||
|
||||
it('should apply multiple themes', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
theme: {
|
||||
themes: ['light', 'traditional'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.applyTheme();
|
||||
|
||||
expect(element.getAttribute('themes')).toBe('light traditional');
|
||||
});
|
||||
|
||||
it('should treat empty themes list as default', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
theme: {
|
||||
themes: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.applyTheme();
|
||||
|
||||
expect(element.getAttribute('themes')).toBe('traditional');
|
||||
});
|
||||
|
||||
it('should apply overrides', () => {
|
||||
const api = createCardAPI();
|
||||
const element = document.createElement('div');
|
||||
vi.mocked(api.getCardElementManager().getElement).mockReturnValue(element);
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||
createConfig({
|
||||
view: {
|
||||
theme: {
|
||||
overrides: {
|
||||
'--test-key': 'test-value',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const manager = new StyleManager(api);
|
||||
|
||||
manager.applyTheme();
|
||||
|
||||
expect(element.style.getPropertyValue('--test-key')).toBe('test-value');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user