From ad6fc61c129b289700fad5708f77e87b03dd6f7f Mon Sep 17 00:00:00 2001 From: Matteo Ciapparelli Date: Sun, 16 Feb 2025 23:22:02 +0100 Subject: [PATCH 1/2] Refactor chart themes and added a default theme --- api/utils.ts | 2 +- config/consts.ts | 4 +- src/chart/styles.ts | 3 ++ src/chart/themes.ts | 24 +++++++++++ src/chart/types/chartOptions.ts | 1 - tests/chart/styles.test.ts | 3 ++ tests/chart/themes.test.ts | 73 +++++++++++++++++++++++++-------- 7 files changed, 89 insertions(+), 21 deletions(-) diff --git a/api/utils.ts b/api/utils.ts index cb18899..e9edf33 100644 --- a/api/utils.ts +++ b/api/utils.ts @@ -104,7 +104,7 @@ export class CustomURLSearchParams extends URLSearchParams { parseTitleOptions(): TitleOptions { return { - text: this.getStringValue('title', 'Bubble Chart'), + text: this.getStringValue('title', 'Most Used Languages'), fontSize: this.getNumberValue('title-size', 24) + 'px', fontWeight: this.getStringValue('title-weight', 'bold'), fill: this.getStringValue( diff --git a/config/consts.ts b/config/consts.ts index bb551a2..6509d3d 100644 --- a/config/consts.ts +++ b/config/consts.ts @@ -1,5 +1,5 @@ import dotenv from 'dotenv'; -import { LightTheme } from '../src/chart/themes.js'; +import { DefaultTheme } from '../src/chart/themes.js'; dotenv.config(); const HOUR_IN_MILLISECONDS = 60 * 60 * 1000; @@ -17,7 +17,7 @@ const CONSTANTS = { DEVICON_URL: process.env.DEVICON_URL!, LINGUIST_GITHUB: process.env.LINGUIST_GITHUB!, LANGUAGE_MAPPINGS_URL: process.env.LANGUAGE_MAPPINGS_URL!, - DEFAULT_THEME: new LightTheme(), + DEFAULT_THEME: new DefaultTheme(), }; CONSTANTS.LANGUAGE_MAPPINGS_URL += CONSTANTS.LANGS_OUTPUT_FILE; diff --git a/src/chart/styles.ts b/src/chart/styles.ts index 288aff1..27f0167 100644 --- a/src/chart/styles.ts +++ b/src/chart/styles.ts @@ -12,6 +12,9 @@ export function getCommonStyles(theme: ThemeBase): string { svg { font-family: ${defaultFontFamily}; background: ${theme.backgroundColor}; + border: ${theme.border}; + border-radius: ${theme.borderRadius}; + padding: ${theme.padding}; } text { fill: ${theme.textColor}; diff --git a/src/chart/themes.ts b/src/chart/themes.ts index 3006e9b..23a0119 100644 --- a/src/chart/themes.ts +++ b/src/chart/themes.ts @@ -1,29 +1,53 @@ export abstract class ThemeBase { public abstract textColor: string; public abstract backgroundColor: string; + public abstract border: string; + public abstract borderRadius: string; + public abstract padding: string; +} + +export class DefaultTheme extends ThemeBase { + public textColor = '#007acc'; + public backgroundColor = 'transparent'; + public border = 'none'; + public borderRadius = '0'; + public padding = '0'; } export class LightTheme extends ThemeBase { public textColor = '#1f2328'; public backgroundColor = '#ffffff'; + public border = `1.5px solid ${this.textColor}77`; + public borderRadius = '.5rem'; + public padding = '.5rem'; } export class DarkTheme extends ThemeBase { public textColor = '#f0f6fc'; public backgroundColor = '#0d1117'; + public border = `1.5px solid ${this.textColor}aa`; + public borderRadius = '.5rem'; + public padding = '.5rem'; } export class DarkHighContrastTheme extends ThemeBase { public textColor = '#ffffff'; public backgroundColor = '#010409'; + public border = `1.5px solid ${this.textColor}`; + public borderRadius = '.5rem'; + public padding = '.5rem'; } export class DarkDimmedTheme extends ThemeBase { public textColor = '#d1d7e0'; public backgroundColor = '#212830'; + public border = `1.5px solid ${this.textColor}55`; + public borderRadius = '.5rem'; + public padding = '.5rem'; } export const themeMap: { [key: string]: ThemeBase } = { + default: new DefaultTheme(), light: new LightTheme(), dark: new DarkTheme(), dark_high_contrast: new DarkHighContrastTheme(), diff --git a/src/chart/types/chartOptions.ts b/src/chart/types/chartOptions.ts index 61470d7..8e1aa05 100644 --- a/src/chart/types/chartOptions.ts +++ b/src/chart/types/chartOptions.ts @@ -19,7 +19,6 @@ export interface TitleOptions { [key: string]: unknown; } -// TODO: add setting for legend position (bottom, left, right, top of chart)? export interface LegendOptions { show: boolean; align: TextAlign; diff --git a/tests/chart/styles.test.ts b/tests/chart/styles.test.ts index f8eb54c..b5e28ad 100644 --- a/tests/chart/styles.test.ts +++ b/tests/chart/styles.test.ts @@ -14,6 +14,9 @@ describe('Styles Tests', () => { const styles = getCommonStyles(theme); expect(styles).toContain(`background: ${theme.backgroundColor}`); expect(styles).toContain(`fill: ${theme.textColor}`); + expect(styles).toContain(`border-radius: ${theme.borderRadius}`); + expect(styles).toContain(`border: ${theme.border}`); + expect(styles).toContain(`padding: ${theme.padding}`); }); it('generateBubbleAnimationStyle generates correct animation styles', () => { diff --git a/tests/chart/themes.test.ts b/tests/chart/themes.test.ts index d88a0bd..4f33bf8 100644 --- a/tests/chart/themes.test.ts +++ b/tests/chart/themes.test.ts @@ -5,37 +5,76 @@ import { DarkHighContrastTheme, DarkDimmedTheme, themeMap, + DefaultTheme, } from '../../src/chart/themes'; describe('Themes', () => { - it('LightTheme properties', () => { + describe('DefaultTheme from themeMap', () => { + const theme = themeMap.default; + + it('should have correct properties', () => { + expect(theme.textColor).toBe('#007acc'); + expect(theme.backgroundColor).toBe('transparent'); + expect(theme.border).toBe('none'); + expect(theme.borderRadius).toBe('0'); + expect(theme.padding).toBe('0'); + }); + }); + describe('LightTheme', () => { const theme = new LightTheme(); - expect(theme.textColor).toBe('#1f2328'); - expect(theme.backgroundColor).toBe('#ffffff'); + + it('should have correct basic properties', () => { + expect(theme.textColor).toBe('#1f2328'); + expect(theme.backgroundColor).toBe('#ffffff'); + expect(theme.border).toBe(`1.5px solid ${theme.textColor}77`); + expect(theme.borderRadius).toBe('.5rem'); + expect(theme.padding).toBe('.5rem'); + }); }); - it('DarkTheme properties', () => { + describe('DarkTheme', () => { const theme = new DarkTheme(); - expect(theme.textColor).toBe('#f0f6fc'); - expect(theme.backgroundColor).toBe('#0d1117'); + + it('should have correct basic properties', () => { + expect(theme.textColor).toBe('#f0f6fc'); + expect(theme.backgroundColor).toBe('#0d1117'); + expect(theme.border).toBe(`1.5px solid ${theme.textColor}aa`); + expect(theme.borderRadius).toBe('.5rem'); + expect(theme.padding).toBe('.5rem'); + }); }); - it('DarkHighContrastTheme properties', () => { + describe('DarkHighContrastTheme', () => { const theme = new DarkHighContrastTheme(); - expect(theme.textColor).toBe('#ffffff'); - expect(theme.backgroundColor).toBe('#010409'); + + it('should have correct basic properties', () => { + expect(theme.textColor).toBe('#ffffff'); + expect(theme.backgroundColor).toBe('#010409'); + expect(theme.border).toBe(`1.5px solid ${theme.textColor}`); + expect(theme.borderRadius).toBe('.5rem'); + expect(theme.padding).toBe('.5rem'); + }); }); - it('DarkDimmedTheme properties', () => { + describe('DarkDimmedTheme', () => { const theme = new DarkDimmedTheme(); - expect(theme.textColor).toBe('#d1d7e0'); - expect(theme.backgroundColor).toBe('#212830'); + + it('should have correct basic properties', () => { + expect(theme.textColor).toBe('#d1d7e0'); + expect(theme.backgroundColor).toBe('#212830'); + expect(theme.border).toBe(`1.5px solid ${theme.textColor}55`); + expect(theme.borderRadius).toBe('.5rem'); + expect(theme.padding).toBe('.5rem'); + }); }); - it('themeMap contains correct themes', () => { - expect(themeMap.light).toBeInstanceOf(LightTheme); - expect(themeMap.dark).toBeInstanceOf(DarkTheme); - expect(themeMap.dark_high_contrast).toBeInstanceOf(DarkHighContrastTheme); - expect(themeMap.dark_dimmed).toBeInstanceOf(DarkDimmedTheme); + describe('themeMap', () => { + it('should contain correct themes', () => { + expect(themeMap.default).toBeInstanceOf(DefaultTheme); + expect(themeMap.light).toBeInstanceOf(LightTheme); + expect(themeMap.dark).toBeInstanceOf(DarkTheme); + expect(themeMap.dark_high_contrast).toBeInstanceOf(DarkHighContrastTheme); + expect(themeMap.dark_dimmed).toBeInstanceOf(DarkDimmedTheme); + }); }); }); From e8fce04b04b342b8c71d16b3086cfa8c43af5938 Mon Sep 17 00:00:00 2001 From: Matteo Ciapparelli Date: Sun, 16 Feb 2025 23:33:03 +0100 Subject: [PATCH 2/2] Add language mappings to .prettierignore --- .prettierignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.prettierignore b/.prettierignore index 77050f3..256f5ab 100644 --- a/.prettierignore +++ b/.prettierignore @@ -34,3 +34,6 @@ ClientBin/ .mfractor/ .ionide/ .husky/ + +# Ignore language mappings +src/languageMappings.json