Skip to content

Commit

Permalink
refactor: 📦 Cleanup code for darkmode (#458)
Browse files Browse the repository at this point in the history
  • Loading branch information
albinmedoc authored Jul 24, 2024
1 parent 2408a59 commit 856fa34
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 58 deletions.
15 changes: 7 additions & 8 deletions apps/wizarr-frontend/src/components/Buttons/ThemeToggle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<VTooltip>
<button class="text-gray-500 dark:text-gray-400 focus:outline-none text-sm" type="button" @click="toggleTheme">
<div :class="iconClasses" class="flex items-center justify-center rounded hover:bg-gray-200 hover:dark:bg-gray-700">
<i v-if="theme == DARK_VALUE" class="fa-solid fa-md fa-cloud-moon"></i>
<i v-if="theme == LIGHT_VALUE" class="fa-solid fa-md fa-sun"></i>
<i v-if="theme == SYSTEM_VALUE" class="fa-solid fa-md fa-desktop"></i>
<i v-if="theme == DARKMODE" class="fa-solid fa-md fa-cloud-moon"></i>
<i v-if="theme == LIGHTMODE" class="fa-solid fa-md fa-sun"></i>
<i v-if="theme == SYSTEMMODE" class="fa-solid fa-md fa-desktop"></i>
</div>
</button>

Expand All @@ -14,20 +14,19 @@
</VTooltip>
</template>


<script lang="ts">
import { defineComponent } from "vue";
import { mapState, mapActions } from "pinia";
import { useThemeStore } from "@/stores/theme";
import { LIGHT_VALUE, DARK_VALUE, SYSTEM_VALUE } from "@/ts/utils/darkMode";
import { LIGHTMODE, DARKMODE, SYSTEMMODE } from "@/ts/utils/darkMode";
export default defineComponent({
name: "ThemeToggle",
data() {
return {
LIGHT_VALUE,
DARK_VALUE,
SYSTEM_VALUE,
LIGHTMODE,
DARKMODE,
SYSTEMMODE,
};
},
props: {
Expand Down
28 changes: 10 additions & 18 deletions apps/wizarr-frontend/src/stores/theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SYSTEM_VALUE, getTheme, updateTheme } from '@/ts/utils/darkMode';
import { SYSTEMMODE, getTheme, updateTheme } from '@/ts/utils/darkMode';

import type { THEME } from '@/ts/utils/darkMode';
import { defineStore } from 'pinia';
Expand All @@ -10,34 +10,26 @@ interface ThemeStoreState {

export const useThemeStore = defineStore('theme', {
state: (): ThemeStoreState => ({
theme: SYSTEM_VALUE,
theme: SYSTEMMODE,
boxView: false,
}),
getters: {
currentTheme: (state) => {
return state.theme;
return getTheme(state.theme);
},
},
actions: {
updateTheme(theme: THEME) {
updateTheme(theme);
},
toggleTheme() {
switch (this.theme) {
case 'dark':
this.theme = 'light';
break;
case 'light':
this.theme = 'system';
break;
case 'system':
this.theme = 'dark';
break;
default:
this.theme = 'dark';
break;
}

const themeTransitions: Record<THEME, THEME> = {
dark: 'light',
light: 'system',
system: 'dark',
};

this.theme = themeTransitions[this.theme];
updateTheme(this.theme);
},
getTheme() {
Expand Down
54 changes: 22 additions & 32 deletions apps/wizarr-frontend/src/ts/utils/darkMode.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,60 @@
type DARK = "dark";
type LIGHT = "light";
type SYSTEM = "system";
const DARKMODE = "dark" as const;
const LIGHTMODE = "light" as const;
const SYSTEMMODE = "system" as const;

declare type THEME = DARK | LIGHT | SYSTEM;
type THEME = typeof DARKMODE | typeof LIGHTMODE | typeof SYSTEMMODE;

const DARK_VALUE: DARK = "dark";
const LIGHT_VALUE: LIGHT = "light";
const SYSTEM_VALUE: SYSTEM = "system";
const getTheme = (theme: THEME = SYSTEMMODE): Omit<THEME, "system"> => {
const systemPrefence = window.matchMedia("(prefers-color-scheme: dark)").matches ? DARKMODE : LIGHTMODE;

const getTheme = (theme?: THEME): THEME => {
const colorTheme = theme ?? (SYSTEM_VALUE as THEME);
const systemPrefence = window.matchMedia("(prefers-color-scheme: dark)").matches ? DARK_VALUE : LIGHT_VALUE;

if (colorTheme === DARK_VALUE) {
return DARK_VALUE;
} else if (colorTheme === LIGHT_VALUE) {
return LIGHT_VALUE;
} else if (colorTheme === SYSTEM_VALUE) {
if (theme === SYSTEMMODE) {
return systemPrefence;
}

return DARK_VALUE;
return theme;
};

const watchTheme = (e: MediaQueryListEvent) => {
// Add event listener for system preference change
if (e.matches) {
// Set the theme to dark
document.documentElement.classList.add(DARK_VALUE);
document.documentElement.classList.remove(LIGHT_VALUE);
document.documentElement.classList.add(DARKMODE);
document.documentElement.classList.remove(LIGHTMODE);
} else {
// Set the theme to light
document.documentElement.classList.add(LIGHT_VALUE);
document.documentElement.classList.remove(DARK_VALUE);
document.documentElement.classList.add(LIGHTMODE);
document.documentElement.classList.remove(DARKMODE);
}
};

const updateTheme = (THEME: THEME): void => {
switch (THEME) {
case DARK_VALUE:
case DARKMODE:
// Set the theme to dark
document.documentElement.classList.add(DARK_VALUE);
document.documentElement.classList.add(DARKMODE);
// Remove event listener for system preference change
window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", watchTheme);
break;
case LIGHT_VALUE:
case LIGHTMODE:
// Set the theme to light
document.documentElement.classList.remove(DARK_VALUE);
document.documentElement.classList.remove(DARKMODE);
// Remove event listener for system preference change
window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", watchTheme);
break;
case SYSTEM_VALUE:
case SYSTEMMODE:
// Get the system preference and set the theme to it
const systemPrefence = window.matchMedia("(prefers-color-scheme: dark)").matches ? DARK_VALUE : LIGHT_VALUE;
const systemPrefence = window.matchMedia("(prefers-color-scheme: dark)").matches ? DARKMODE : LIGHTMODE;
document.documentElement.classList.add(systemPrefence);
document.documentElement.classList.remove(systemPrefence === DARK_VALUE ? LIGHT_VALUE : DARK_VALUE);
document.documentElement.classList.remove(systemPrefence === DARKMODE ? LIGHTMODE : DARKMODE);

// Add event listener for system preference change
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", watchTheme);
break;
default:
// Set the theme to dark
document.documentElement.classList.add(DARK_VALUE);
document.documentElement.classList.add(DARKMODE);
break;
}
};

export { getTheme, updateTheme, DARK_VALUE, LIGHT_VALUE, SYSTEM_VALUE };
export type { THEME, DARK, LIGHT, SYSTEM };
export { getTheme, updateTheme, DARKMODE, LIGHTMODE, SYSTEMMODE };
export type { THEME };

0 comments on commit 856fa34

Please sign in to comment.