105 lines
3.7 KiB
TypeScript
105 lines
3.7 KiB
TypeScript
import {
|
|
applyThemeToCss,
|
|
clearThemeCss,
|
|
Theme,
|
|
} from '../../frontend/src/app/core/services/bootstrap.types';
|
|
|
|
function makeClassicTheme(): Theme {
|
|
return {
|
|
id: 'classic',
|
|
name: 'Classic',
|
|
tokens: {
|
|
primary: '#3b82f6',
|
|
secondary: '#64748b',
|
|
accent: '#f59e0b',
|
|
surface: '#ffffff',
|
|
text: '#0f172a',
|
|
success: '#10b981',
|
|
warning: '#f59e0b',
|
|
danger: '#ef4444',
|
|
fontFamily: 'system-ui, sans-serif',
|
|
radii: { sm: '4px', md: '8px', lg: '16px' },
|
|
spacingScale: [4, 8, 12, 16, 24, 32, 48],
|
|
},
|
|
};
|
|
}
|
|
|
|
function makeMonochromeTheme(): Theme {
|
|
return {
|
|
id: 'monochrome',
|
|
name: 'Monochrome',
|
|
tokens: {
|
|
primary: '#000000',
|
|
secondary: '#525252',
|
|
accent: '#a3a3a3',
|
|
surface: '#ffffff',
|
|
text: '#0a0a0a',
|
|
success: '#404040',
|
|
warning: '#737373',
|
|
danger: '#171717',
|
|
fontFamily: 'system-ui, sans-serif',
|
|
radii: { sm: '0', md: '0', lg: '0' },
|
|
spacingScale: [4, 8, 12, 16, 24, 32, 48],
|
|
},
|
|
};
|
|
}
|
|
|
|
describe('applyThemeToCss', () => {
|
|
beforeEach(() => {
|
|
clearThemeCss();
|
|
});
|
|
|
|
it('writes all CSS custom properties from the Classic theme tokens', () => {
|
|
applyThemeToCss(makeClassicTheme());
|
|
const root = document.documentElement.style;
|
|
expect(root.getPropertyValue('--color-primary')).toBe('#3b82f6');
|
|
expect(root.getPropertyValue('--color-secondary')).toBe('#64748b');
|
|
expect(root.getPropertyValue('--color-accent')).toBe('#f59e0b');
|
|
expect(root.getPropertyValue('--color-surface')).toBe('#ffffff');
|
|
expect(root.getPropertyValue('--color-text')).toBe('#0f172a');
|
|
expect(root.getPropertyValue('--color-success')).toBe('#10b981');
|
|
expect(root.getPropertyValue('--color-warning')).toBe('#f59e0b');
|
|
expect(root.getPropertyValue('--color-danger')).toBe('#ef4444');
|
|
expect(root.getPropertyValue('--font-family')).toBe('system-ui, sans-serif');
|
|
expect(root.getPropertyValue('--radius-sm')).toBe('4px');
|
|
expect(root.getPropertyValue('--radius-md')).toBe('8px');
|
|
expect(root.getPropertyValue('--radius-lg')).toBe('16px');
|
|
});
|
|
|
|
it('returns false and is a no-op when the theme is missing tokens', () => {
|
|
expect(applyThemeToCss(null)).toBe(false);
|
|
expect(applyThemeToCss(undefined)).toBe(false);
|
|
expect(applyThemeToCss({ id: 'x', name: 'X' } as unknown as Theme)).toBe(false);
|
|
const root = document.documentElement.style;
|
|
expect(root.getPropertyValue('--color-primary')).toBe('');
|
|
expect(root.getPropertyValue('--radius-md')).toBe('');
|
|
});
|
|
|
|
it('replaces Classic tokens with Monochrome tokens when re-applied', () => {
|
|
applyThemeToCss(makeClassicTheme());
|
|
applyThemeToCss(makeMonochromeTheme());
|
|
const root = document.documentElement.style;
|
|
expect(root.getPropertyValue('--color-primary')).toBe('#000000');
|
|
expect(root.getPropertyValue('--color-text')).toBe('#0a0a0a');
|
|
expect(root.getPropertyValue('--radius-md')).toBe('0');
|
|
expect(root.getPropertyValue('--radius-sm')).toBe('0');
|
|
expect(root.getPropertyValue('--radius-lg')).toBe('0');
|
|
});
|
|
|
|
it('treats the zero-valued Monochrome radius as a valid applied value', () => {
|
|
applyThemeToCss(makeMonochromeTheme());
|
|
expect(document.documentElement.style.getPropertyValue('--radius-md')).toBe('0');
|
|
});
|
|
});
|
|
|
|
describe('clearThemeCss', () => {
|
|
it('removes every theme CSS custom property set by applyThemeToCss', () => {
|
|
applyThemeToCss(makeClassicTheme());
|
|
clearThemeCss();
|
|
const root = document.documentElement.style;
|
|
expect(root.getPropertyValue('--color-primary')).toBe('');
|
|
expect(root.getPropertyValue('--color-text')).toBe('');
|
|
expect(root.getPropertyValue('--radius-md')).toBe('');
|
|
expect(root.getPropertyValue('--font-family')).toBe('');
|
|
});
|
|
}); |