From 7e15cd3412f416809f4d9be6edf161df1582ec3f Mon Sep 17 00:00:00 2001 From: angbur <41025473+angbur@users.noreply.github.com> Date: Tue, 6 Dec 2022 15:29:48 +0100 Subject: [PATCH] Issue 97 dark mode (#105) --- src/components/atoms/divider.astro | 2 +- src/components/atoms/icon-button.astro | 2 + src/components/atoms/labelled-value.astro | 4 +- src/components/atoms/section-card.astro | 2 +- src/components/atoms/sidebar-item.tsx | 6 ++- src/components/atoms/skill-level-tile.astro | 2 +- src/components/atoms/tag.astro | 4 +- src/components/atoms/theme-icon.tsx | 49 +++++++++++++++++++++ src/components/atoms/tooltip.tsx | 5 ++- src/components/atoms/typography.astro | 20 ++++----- src/components/organisms/sidebar.astro | 2 +- src/components/organisms/skill.astro | 2 +- src/components/sections/main-section.astro | 4 +- src/pages/index.astro | 4 +- src/types/icon.ts | 4 +- tailwind.config.cjs | 1 + 16 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 src/components/atoms/theme-icon.tsx diff --git a/src/components/atoms/divider.astro b/src/components/atoms/divider.astro index 58375f6..89f639e 100644 --- a/src/components/atoms/divider.astro +++ b/src/components/atoms/divider.astro @@ -1 +1 @@ -
+
diff --git a/src/components/atoms/icon-button.astro b/src/components/atoms/icon-button.astro index d91548a..85909d2 100644 --- a/src/components/atoms/icon-button.astro +++ b/src/components/atoms/icon-button.astro @@ -35,6 +35,8 @@ const { icon, href, target, size, ...rest } = Astro.props; 'focus:ring-2', 'focus:ring-offset-2', 'focus:ring-primary-500', + 'dark:bg-gray-600', + 'dark:text-gray-200', sizeMap[size], ]} {...rest} diff --git a/src/components/atoms/labelled-value.astro b/src/components/atoms/labelled-value.astro index 62c9e2f..c1c5fda 100644 --- a/src/components/atoms/labelled-value.astro +++ b/src/components/atoms/labelled-value.astro @@ -8,6 +8,6 @@ const { label, value } = Astro.props; ---
- {label}: - {value} + {label}: + {value}
diff --git a/src/components/atoms/section-card.astro b/src/components/atoms/section-card.astro index 3a6f256..f9a41a4 100644 --- a/src/components/atoms/section-card.astro +++ b/src/components/atoms/section-card.astro @@ -8,4 +8,4 @@ export interface Props { const { section } = Astro.props; --- -
+
diff --git a/src/components/atoms/sidebar-item.tsx b/src/components/atoms/sidebar-item.tsx index 0887f13..d740325 100644 --- a/src/components/atoms/sidebar-item.tsx +++ b/src/components/atoms/sidebar-item.tsx @@ -24,7 +24,11 @@ const SidebarItem = ({ section, icon, title = '' }: SidebarItemProps) => { = tileLevel; 'last:rounded-r-sm', 'first:rounded-l-sm', 'first:rounded-r-none', - { 'bg-gray-500': isFilled, 'bg-gray-300': !isFilled }, + { 'dark:bg-gray-300': isFilled, 'dark:bg-gray-500': !isFilled, 'bg-gray-200': !isFilled, 'bg-gray-500': isFilled }, ]} > diff --git a/src/components/atoms/tag.astro b/src/components/atoms/tag.astro index dd50485..54eebe7 100644 --- a/src/components/atoms/tag.astro +++ b/src/components/atoms/tag.astro @@ -10,7 +10,9 @@ export interface Props { const { name, color } = Astro.props; --- -
+
diff --git a/src/components/atoms/theme-icon.tsx b/src/components/atoms/theme-icon.tsx new file mode 100644 index 0000000..ebd2cf0 --- /dev/null +++ b/src/components/atoms/theme-icon.tsx @@ -0,0 +1,49 @@ +import { useEffect, useState } from 'react'; + +import Icon from './icon'; + +const STORAGE_THEME_KEY = 'theme'; +const DARK_THEME_KEY = 'dark'; +const LIGHT_THEME_KEY = 'light'; + +type ThemeVariant = typeof DARK_THEME_KEY | typeof LIGHT_THEME_KEY; + +const getInitialTheme = (): ThemeVariant => { + if (typeof localStorage !== 'undefined' && localStorage.getItem(STORAGE_THEME_KEY)) { + return localStorage.getItem(STORAGE_THEME_KEY) === LIGHT_THEME_KEY ? LIGHT_THEME_KEY : DARK_THEME_KEY; + } + if (window.matchMedia(`(prefers-color-scheme: ${DARK_THEME_KEY})`).matches) { + return DARK_THEME_KEY; + } + return LIGHT_THEME_KEY; +}; + +const ThemeToggle = () => { + const [theme, setTheme] = useState(() => getInitialTheme()); + + const handleClick = () => { + setTheme((prev) => (prev === LIGHT_THEME_KEY ? DARK_THEME_KEY : LIGHT_THEME_KEY)); + }; + + useEffect(() => { + if (theme === DARK_THEME_KEY) { + document.documentElement.classList.add(DARK_THEME_KEY); + } + if (theme === LIGHT_THEME_KEY) { + document.documentElement.classList.remove(DARK_THEME_KEY); + } + localStorage.setItem(STORAGE_THEME_KEY, theme); + }, [theme]); + + return ( + + ); +}; + +export default ThemeToggle; diff --git a/src/components/atoms/tooltip.tsx b/src/components/atoms/tooltip.tsx index 7f4c308..cbe8e6e 100644 --- a/src/components/atoms/tooltip.tsx +++ b/src/components/atoms/tooltip.tsx @@ -11,7 +11,10 @@ const Tooltip = ({ children, content, placement = 'top' }: TooltipProps) => { return ( ( -
+
{content}
)} diff --git a/src/components/atoms/typography.astro b/src/components/atoms/typography.astro index 9a5535d..7742a18 100644 --- a/src/components/atoms/typography.astro +++ b/src/components/atoms/typography.astro @@ -25,16 +25,16 @@ const variantToElement = { } as const; const variantToClassName = { - 'main-title': 'text-3xl sm:text-4xl font-extrabold text-gray-900', - 'main-subtitle': 'text-md sm:text-lg font-medium text-gray-700', - 'section-title': 'text-3xl font-extrabold text-gray-900', - 'section-subtitle': 'text-lg font-extrabold text-gray-900', - 'item-title': 'text-xl font-extrabold text-gray-900', - 'item-title-suffix': 'text-xl font-medium text-gray-700', - 'item-subtitle': 'text-md font-medium text-gray-700', - 'tile-title': 'text-sm font-medium text-gray-700', - 'tile-subtitle': 'text-sm font-normal text-gray-500', - paragraph: 'text-sm sm:text-base leading-relaxed font-normal text-gray-500', + 'main-title': 'text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-gray-100', + 'main-subtitle': 'text-md sm:text-lg font-medium text-gray-700 dark:text-gray-100', + 'section-title': 'text-3xl font-extrabold text-gray-900 dark:text-gray-100', + 'section-subtitle': 'text-lg font-extrabold text-gray-900 dark:text-gray-100', + 'item-title': 'text-xl font-extrabold text-gray-900 dark:text-gray-100', + 'item-title-suffix': 'text-xl font-medium text-gray-700 dark:text-gray-100', + 'item-subtitle': 'text-md font-medium text-gray-700 dark:text-gray-100', + 'tile-title': 'text-sm font-medium text-gray-700 dark:text-gray-200', + 'tile-subtitle': 'text-sm font-normal text-gray-500 dark:text-gray-300', + paragraph: 'text-sm sm:text-base leading-relaxed font-normal text-gray-500 dark:text-gray-300', }; export interface Props extends Omit { diff --git a/src/components/organisms/sidebar.astro b/src/components/organisms/sidebar.astro index 46bd799..73c8ee6 100644 --- a/src/components/organisms/sidebar.astro +++ b/src/components/organisms/sidebar.astro @@ -5,6 +5,6 @@ export interface Props { const { className } = Astro.props; --- -