Skip to content

Commit

Permalink
fix: fix theme toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
fbuireu committed May 30, 2024
1 parent 0268584 commit 3cdfa36
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 74 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"react-hook-form": "^7.51.5",
"react-router-dom": "^6.23.1",
"resend": "^3.2.0",
"swiper": "^11.1.3",
"swiper": "^11.1.4",
"three": "^0.164.1",
"zod": "^3.23.8"
},
Expand Down
15 changes: 5 additions & 10 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { defineAction, z, ActionError } from "astro:actions";
import { DEFAULT_LOCALE_STRING } from "../consts.ts";
import { DEFAULT_LOCALE_STRING } from "src/consts.ts";
import { sendEmail } from "@server/email/server.ts";
import { app } from "@server/firebase/server.ts";
import { getFirestore } from "firebase-admin/firestore";
import type { FormData } from "@components/organisms/contactForm";

type ContactDetails = Omit<FormData, "recaptcha">;

const contactFormSchema = z
.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
message: z.string(),
date: z.union([z.date(), z.string()]),
})
.omit({ id: true, date: true });
const contactFormSchema = z.object({
name: z.string(),
email: z.string().email(),
});

const database = getFirestore(app);

Expand Down
3 changes: 3 additions & 0 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const CONTACT_DETAILS: Record<string, string> = {
ENCODED_BIANCA_EMAIL: btoa("[email protected]"),
};

export const THEME_STORAGE_KEY = "theme";

//todo: isolate types
interface MeshPhongMaterialConfig {
TRANSPARENT: boolean;
COLOR: string;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import Testimonials from "@components/organisms/testimonials/Testimonials.astro"
import MyWork from "@components/organisms/myWork/MyWork.astro";
import LatestArticles from "@components/organisms/latestArticles/LatestArticles.astro";
// todo: tags page
// todo: cookies and acceptance
// todo: add thinner svg lines
// todo: tags page
// todo: when press arrows (keyboard) simulate click in slider arrows
// todo: add resume (PDF) in about?
// todo: dynamic content
Expand Down
2 changes: 1 addition & 1 deletion src/server/email/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Resend } from "resend";
import { CONTACT_DETAILS } from "../../consts.ts";
import { CONTACT_DETAILS } from "src/consts.ts";
import type { FormData } from "@components/organisms/contactForm";

type ContactDetails = Omit<FormData, "recaptcha">;
Expand Down
2 changes: 1 addition & 1 deletion src/ui/components/atoms/scrollTop/ScrollTop.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "./scroll-top.css";
---

<div class="scroll-top__wrapper">
<a class="scroll-top flex" href="#top">
<a class="scroll-top flex clickable" href="#top">
<Fragment set:html={arrowUp} />
</a>
</div>
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
enum ThemeType {
import { THEME_STORAGE_KEY } from "src/consts.ts";

export enum ThemeType {
DARK = "dark",
LIGHT = "light",
}

const THEME_STORAGE_KEY = "theme";
const PREFERS_DARK_SCHEME = window.matchMedia("(prefers-color-scheme: dark)");
const THEME_TOGGLE_INPUT = document.querySelector<HTMLInputElement>('.theme-toggle input[type="checkbox"]');
const THEME_TOGGLE = document.querySelector<HTMLInputElement>(".theme-toggle");

const getInitialTheme = (): ThemeType => {
const cachedTheme = localStorage.getItem(THEME_STORAGE_KEY) as ThemeType | null;
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
const prefersDarkScheme = PREFERS_DARK_SCHEME.matches;

return cachedTheme ?? (prefersDarkScheme ? ThemeType.DARK : ThemeType.LIGHT);
};

const applyTheme = (theme: ThemeType) => {
document.documentElement.setAttribute(`data-${THEME_STORAGE_KEY}`, theme);
localStorage.setItem(THEME_STORAGE_KEY, theme);
const themeToggle = document.querySelector<HTMLInputElement>(".theme-toggle");

if (!themeToggle) return;

if (theme === ThemeType.DARK) {
themeToggle.classList.add("dark", "--toggled");
themeToggle.classList.remove("--untoggled");
} else {
themeToggle.classList.add("--untoggled");
themeToggle.classList.remove("dark", "--toggled");
}
};
if (!THEME_TOGGLE || !THEME_TOGGLE_INPUT) return;

const syncToggleSwitch = (toggleSwitch: HTMLInputElement, theme: ThemeType) => {
toggleSwitch.checked = theme === ThemeType.DARK;
THEME_TOGGLE_INPUT.checked = theme === ThemeType.DARK;
THEME_TOGGLE.classList.toggle("dark", theme === ThemeType.DARK);
THEME_TOGGLE.classList.toggle("--toggled", theme === ThemeType.DARK);
THEME_TOGGLE.classList.toggle("--untoggled", theme !== ThemeType.DARK);
};

const handleThemeChange = (toggleSwitch: HTMLInputElement) => {
Expand All @@ -37,24 +34,23 @@ const handleThemeChange = (toggleSwitch: HTMLInputElement) => {
};

export const initializeThemeSetter = () => {
const toggleSwitch = document.querySelector<HTMLInputElement>('.theme-toggle input[type="checkbox"]');
const initialTheme = getInitialTheme();

applyTheme(initialTheme);

if (!toggleSwitch) return;
if (!THEME_TOGGLE_INPUT) return;

syncToggleSwitch(toggleSwitch, initialTheme);
toggleSwitch.addEventListener("change", () => handleThemeChange(toggleSwitch));
THEME_TOGGLE_INPUT.addEventListener("change", () => handleThemeChange(THEME_TOGGLE_INPUT));

window.addEventListener("storage", (event) => {
if (event.key === THEME_STORAGE_KEY && event.newValue) {
const newTheme = event.newValue as ThemeType;
applyTheme(newTheme);

if (!toggleSwitch) return;

syncToggleSwitch(toggleSwitch, newTheme);
if (newTheme !== initialTheme) applyTheme(newTheme);
}
});

PREFERS_DARK_SCHEME.addEventListener("change", (event) => {
const newTheme = event.matches ? ThemeType.DARK : ThemeType.LIGHT;
applyTheme(newTheme);
});
};
7 changes: 5 additions & 2 deletions src/ui/components/atoms/worldGlobe/WorldGlobe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import * as Three from "three";
import countries from "@data/countries.geojson.json";
import "./world-globe.css";
import { calculateCenter } from "@components/atoms/worldGlobe/utils/calculateCenter";
import { WORLD_GLOBE_CONFIG } from "src/consts.ts";
import { THEME_STORAGE_KEY, WORLD_GLOBE_CONFIG } from "src/consts.ts";
import { renderPin } from "@components/atoms/worldGlobe/utils/renderPin";
import type { ReactGlobePoint } from "./utils/refineCities";
import { refineCities } from "./utils/refineCities";
import horizontalArrow from "@assets/images/svg/left-arrow.svg";
import zoomIn from "@assets/images/svg/zoom-in.svg";
import zoomOut from "@assets/images/svg/zoom-out.svg";
import useTabVisibility, { TabVisibility } from "@ui/hooks/useTabVisibility/useTabVisibility.ts";
import { ThemeType } from "@components/atoms/themeToggle/utils/themeSetter";

export interface City {
latitude: string;
Expand Down Expand Up @@ -78,6 +79,8 @@ const WorldGlobe = memo(({ cities, width = worldGlobeSize.width }: GlobeAllCitie
});
};

const isDarkMode = () => localStorage.getItem(THEME_STORAGE_KEY) === ThemeType.DARK;

useEffect(() => {
if (!worldGlobeReference.current) return;
worldGlobeReference.current.controls().autoRotate = document.visibilityState === TabVisibility.VISIBLE;
Expand Down Expand Up @@ -111,7 +114,7 @@ const WorldGlobe = memo(({ cities, width = worldGlobeSize.width }: GlobeAllCitie
pointsMerge={POINTS_MERGE}
animateIn={ANIMATE_IN}
showAtmosphere={SHOW_ATMOSPHERE}
backgroundColor={BACKGROUND_COLOR}
backgroundColor={isDarkMode() ? "#1E2021FF" : BACKGROUND_COLOR}
hexPolygonsData={countries.features}
hexPolygonColor={() => HEXAGON_POLYGON_COLOR}
globeMaterial={
Expand Down
6 changes: 6 additions & 0 deletions src/ui/components/organisms/testimonials/testimonials.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
.testimonials__wrapper {
background-color: var(--neutral-light-4);
margin: 5rem 0;
transition: background-color 0.3s ease;

@media (max-width: 960px) {
margin: 0;
}

[data-theme="dark"] & {
background-color: var(--background-main);
}
}

.testimonials__title,
Expand All @@ -27,6 +32,7 @@
max-width: var(--grid-small);
padding: 2rem 0;
width: 100%;

@media (max-width: 960px) {
padding: 0;
}
Expand Down
56 changes: 28 additions & 28 deletions src/ui/styles/global/variables.css
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
@layer theme {
:root {
color-scheme: light dark;
--primary-light-3: light-dark(color-mix(in srgb, var(--primary-main), var(--white) 75%), color-mix(in srgb, var(--primary-main), var(--black) 75%));
--primary-light-2: light-dark(color-mix(in srgb, var(--primary-main), var(--white) 50%), color-mix(in srgb, var(--primary-main), var(--black) 50%));
--primary-light-1: light-dark(color-mix(in srgb, var(--primary-main), var(--white) 25%), color-mix(in srgb, var(--primary-main), var(--black) 25%));
--primary-light-3: color-mix(in srgb, var(--primary-main), var(--white) 75%);
--primary-light-2: color-mix(in srgb, var(--primary-main), var(--white) 50%);
--primary-light-1: color-mix(in srgb, var(--primary-main), var(--white) 25%);
--primary-main: oklch(74.41% 0.108 75.17);
--primary-dark-1: light-dark(color-mix(in srgb, var(--primary-main), var(--black) 25%), color-mix(in srgb, var(--primary-main), var(--white) 25%));
--primary-dark-2: light-dark(color-mix(in srgb, var(--primary-main), var(--black) 50%), color-mix(in srgb, var(--primary-main), var(--white) 50%));
--primary-dark-3: light-dark(color-mix(in srgb, var(--primary-main), var(--black) 75%), color-mix(in srgb, var(--primary-main), var(--white) 75%));
--neutral-main: light-dark(oklch(24.18% 0.004 228.95), oklch(90.49% 0.003 48.72));
--neutral-light-1: light-dark(color-mix(in srgb, var(--neutral-main), var(--white) 25%), color-mix(in srgb, var(--neutral-main), var(--black) 25%));
--neutral-light-2: light-dark(color-mix(in srgb, var(--neutral-main), var(--white) 50%), color-mix(in srgb, var(--neutral-main), var(--black) 50%));
--neutral-light-3: light-dark(color-mix(in srgb, var(--neutral-main), var(--white) 75%), color-mix(in srgb, var(--neutral-main), var(--black) 75%));
--neutral-light-4: light-dark(color-mix(in srgb, var(--neutral-main), var(--white) 95%), color-mix(in srgb, var(--neutral-main), var(--black) 95%));
--background-main: light-dark(var(--white), oklch(24.18% 0.004 228.95));
--primary-dark-1: color-mix(in srgb, var(--primary-main), var(--black) 25%);
--primary-dark-2: color-mix(in srgb, var(--primary-main), var(--black) 50%);
--primary-dark-3: color-mix(in srgb, var(--primary-main), var(--black) 75%);
--neutral-main: oklch(24.18% 0.004 228.95);
--neutral-light-1: color-mix(in srgb, var(--neutral-main), var(--white) 25%);
--neutral-light-2: color-mix(in srgb, var(--neutral-main), var(--white) 50%);
--neutral-light-3: color-mix(in srgb, var(--neutral-main), var(--white) 75%);
--neutral-light-4: color-mix(in srgb, var(--neutral-main), var(--white) 95%);
--background-main: oklch(100% 0 0);
--error-main: oklch(58.08% 0.196 25.77);
--success-main: oklch(52.29% 0.17558211290701223 142.8999328999691);
--x: oklch(0 0 0);
--facebook: oklch(47.24% 0.108 263.58);
--linkedin: oklch(54.58% 0.13 242.27);
--whatsapp: oklch(76.1% 0.201 149.97);
--email: oklch(58.97% 0 0);
--white: light-dark(oklch(100% 0 0), oklch(0 0 0));
--black: light-dark(oklch(0 0 0), oklch(100% 0 0));
--white: oklch(100% 0 0);
--black: oklch(0 0 0);
--header-height: 80px;
--global-max-width: 1440px;
--base-font-size: 16px;
Expand All @@ -42,20 +42,20 @@
}

[data-theme="dark"] {
--primary-light-3: light-dark(color-mix(in srgb, var(--primary-main), var(--black) 75%), color-mix(in srgb, var(--primary-main), var(--white) 75%));
--primary-light-2: light-dark(color-mix(in srgb, var(--primary-main), var(--black) 50%), color-mix(in srgb, var(--primary-main), var(--white) 50%));
--primary-light-1: light-dark(color-mix(in srgb, var(--primary-main), var(--black) 25%), color-mix(in srgb, var(--primary-main), var(--white) 25%));
--primary-dark-1: light-dark(color-mix(in srgb, var(--primary-main), var(--white) 25%), color-mix(in srgb, var(--primary-main), var(--black) 25%));
--primary-dark-2: light-dark(color-mix(in srgb, var(--primary-main), var(--white) 50%), color-mix(in srgb, var(--primary-main), var(--black) 50%));
--primary-dark-3: light-dark(color-mix(in srgb, var(--primary-main), var(--white) 75%), color-mix(in srgb, var(--primary-main), var(--black) 75%));
--neutral-main: light-dark(oklch(90.49% 0.003 48.72), oklch(24.18% 0.004 228.95));
--neutral-light-1: light-dark(color-mix(in srgb, var(--neutral-main), var(--black) 25%), color-mix(in srgb, var(--neutral-main), var(--white) 25%));
--neutral-light-2: light-dark(color-mix(in srgb, var(--neutral-main), var(--black) 50%), color-mix(in srgb, var(--neutral-main), var(--white) 50%));
--neutral-light-3: light-dark(color-mix(in srgb, var(--neutral-main), var(--black) 75%), color-mix(in srgb, var(--neutral-main), var(--white) 75%));
--neutral-light-4: light-dark(color-mix(in srgb, var(--neutral-main), var(--black) 95%), color-mix(in srgb, var(--neutral-main), var(--white) 95%));
--background-main: light-dark(oklch(24.18% 0.004 228.95), var(--white));
--white: light-dark(oklch(0 0 0), oklch(100% 0 0));
--black: light-dark(oklch(100% 0 0), oklch(0 0 0));
--primary-light-3: color-mix(in srgb, var(--primary-main), var(--black) 75%);
--primary-light-2: color-mix(in srgb, var(--primary-main), var(--black) 50%);
--primary-light-1: color-mix(in srgb, var(--primary-main), var(--black) 25%);
--primary-dark-1: color-mix(in srgb, var(--primary-main), var(--white) 25%);
--primary-dark-2: color-mix(in srgb, var(--primary-main), var(--white) 50%);
--primary-dark-3: color-mix(in srgb, var(--primary-main), var(--white) 75%);
--neutral-main: oklch(90.49% 0.003 48.72);
--neutral-light-1: color-mix(in srgb, var(--neutral-main), var(--black) 25%);
--neutral-light-2: color-mix(in srgb, var(--neutral-main), var(--black) 50%);
--neutral-light-3: color-mix(in srgb, var(--neutral-main), var(--black) 75%);
--neutral-light-4: color-mix(in srgb, var(--neutral-main), var(--black) 95%);
--background-main: oklch(24.18% 0.004 228.95);
--white: oklch(0 0 0);
--black: oklch(100% 0 0);
}

@property --primary-light-3 {
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4395,7 +4395,7 @@ __metadata:
stylelint: "npm:^16.6.1"
stylelint-config-recommended: "npm:^14.0.0"
stylelint-order: "npm:^6.0.4"
swiper: "npm:^11.1.3"
swiper: "npm:^11.1.4"
three: "npm:^0.164.1"
typescript: "npm:^5.4.5"
vitest: "npm:^1.6.0"
Expand Down Expand Up @@ -11325,10 +11325,10 @@ __metadata:
languageName: node
linkType: hard

"swiper@npm:^11.1.3":
version: 11.1.3
resolution: "swiper@npm:11.1.3"
checksum: 10c0/add208824c4986ede3b000a884073b2a31ba7656f7f8362d4cdcd40d79e75b55bb57e7b7d5e1dd88c6118a11b4cf5c102d49429653b1c7d7edd5cb25b811ccd7
"swiper@npm:^11.1.4":
version: 11.1.4
resolution: "swiper@npm:11.1.4"
checksum: 10c0/a1e4b87f414f67f5da6a07b33d5ee20e54062d21f8bed88195d5d56decff6afddf683e130118b7fa12668de221f794ae63f6c073761b683a4b90bbd5eb585202
languageName: node
linkType: hard

Expand Down

0 comments on commit 3cdfa36

Please sign in to comment.