From 75fa8117f66429a5c0640d58922f4898a11d35cf Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 27 Jul 2022 22:38:43 +0300 Subject: [PATCH] theme toggling --- package.json | 2 +- public/assets/dark.css | 29 ---- public/assets/light.css | 23 --- src/components/ArticleItem/ArticleItem.tsx | 4 +- src/components/ArticlePost/ArticlePost.astro | 2 - src/components/ArticlesList/ArticlesList.tsx | 1 - src/components/BaseHead.astro | 8 +- .../ContactsList/ContactsList.astro | 6 +- src/components/Header/Header.astro | 2 +- src/components/Header/Header.scss | 50 +------ .../Header/NavToggle/NavToggle.scss | 4 +- src/components/Header/NavToggle/NavToggle.tsx | 13 +- src/components/ProjectItem/ProjectItem.astro | 2 - .../RecentArticles/RecentArticles.astro | 2 - src/components/SearchInput/SearchInput.scss | 2 +- src/components/SearchInput/SearchInput.tsx | 2 +- src/components/SkillsBlock/SkillsBlock.astro | 2 - .../ThemeSwticher/ThemeSwitcher.astro | 8 - .../ThemeSwticher/ThemeSwitcher.scss | 5 + .../ThemeSwticher/ThemeSwitcher.tsx | 62 ++++++++ src/components/ThemeSwticher/index.ts | 2 +- src/config.ts | 4 + src/layouts/article.astro | 1 - src/layouts/default.astro | 2 +- src/pages/articles.astro | 2 - src/pages/index.astro | 2 - src/scripts/detect-theme.astro | 20 +++ src/scripts/index.ts | 1 + src/styles/global.scss | 101 +------------ src/styles/theme.scss | 140 ++++++++++++++++++ src/types/index.ts | 25 ---- src/types/main.d.ts | 39 +++++ src/utils/articles.ts | 2 - tsconfig.json | 3 +- 34 files changed, 304 insertions(+), 269 deletions(-) delete mode 100644 public/assets/dark.css delete mode 100644 public/assets/light.css delete mode 100644 src/components/ThemeSwticher/ThemeSwitcher.astro create mode 100644 src/components/ThemeSwticher/ThemeSwitcher.tsx create mode 100644 src/scripts/detect-theme.astro create mode 100644 src/scripts/index.ts create mode 100644 src/styles/theme.scss delete mode 100644 src/types/index.ts create mode 100644 src/types/main.d.ts diff --git a/package.json b/package.json index fcaa6d9..d6d80cf 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "dev": "astro dev --host", "start": "astro dev", - "build": "astro build", + "build": "astro check && tsc --noEmit && astro build", "preview": "astro preview --host", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json}\"", "lint": "eslint '**/*.{js,mjs,ts,tsx}'" diff --git a/public/assets/dark.css b/public/assets/dark.css deleted file mode 100644 index b6ec3e2..0000000 --- a/public/assets/dark.css +++ /dev/null @@ -1,29 +0,0 @@ -:root { - /* Fonts */ - --font-color: var(--color-white); - --font-color-gray: var(--color-gray-100); - --font-color-grayer: var(--color-gray-200); - - /* Border */ - --border-color: var(--color-gray-700); - --border-color-hover: var(--color-gray-600); - - /* Elements */ - --background-body-color: var(--color-gray-900); - --background-header-color: var(--color-gray-900); - --background-inline-code: var(--color-gray-800); - --background-color-hover: var(--color-gray-800); - --background-btn-link: var(--color-gray-800); - --background-btn-link-active: var(--color-gray-700); - --background-inputs-color: var(--color-gray-800); - - /* Icons */ - --icon-primary: var(--color-white); - --icon-secondary: var(--color-gray-100); - --icon-filter: invert(100%); -} - -.header svg, -.site-content svg { - filter: var(--icon-filter); -} diff --git a/public/assets/light.css b/public/assets/light.css deleted file mode 100644 index 1daf165..0000000 --- a/public/assets/light.css +++ /dev/null @@ -1,23 +0,0 @@ -:root { - /* Fonts */ - --font-color: var(--color-black); - --font-color-gray: var(--color-gray-500); - --font-color-grayer: var(--color-gray-700); - - /* Border */ - --border-color: var(--color-gray-100); - --border-color-hover: var(--color-gray-400); - - /* Elements */ - --background-body-color: var(--color-white); - --background-header-color: var(--color-white); - --background-inline-code: rgba(0, 0, 0, 0.05); - --background-color-hover: var(--color-gray-50); - --background-btn-link: var(--color-white); - --background-btn-link-active: var(--color-white); - --background-inputs-color: var(--color-white); - - /* Icons */ - --icon-primary: var(--color-white); - --icon-secondary: var(--color-gray-700); -} diff --git a/src/components/ArticleItem/ArticleItem.tsx b/src/components/ArticleItem/ArticleItem.tsx index b23fe7c..7dd8672 100644 --- a/src/components/ArticleItem/ArticleItem.tsx +++ b/src/components/ArticleItem/ArticleItem.tsx @@ -1,8 +1,6 @@ -import type { ArticleType } from '@root/types'; - -import './ArticleItem.scss'; import { Component } from 'solid-js'; import { DateFormatter } from '@utils/date'; +import './ArticleItem.scss'; export type ArticleItemProps = { data: ArticleType; diff --git a/src/components/ArticlePost/ArticlePost.astro b/src/components/ArticlePost/ArticlePost.astro index 282e96f..9afa411 100644 --- a/src/components/ArticlePost/ArticlePost.astro +++ b/src/components/ArticlePost/ArticlePost.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import { DateFormatter } from '@root/utils'; import './ArticlePost.scss'; diff --git a/src/components/ArticlesList/ArticlesList.tsx b/src/components/ArticlesList/ArticlesList.tsx index f12f06e..9f5723f 100644 --- a/src/components/ArticlesList/ArticlesList.tsx +++ b/src/components/ArticlesList/ArticlesList.tsx @@ -1,5 +1,4 @@ import type { Component } from 'solid-js'; -import type { ArticleBlockType } from '@root/types'; import { createSignal, createEffect, For } from 'solid-js'; import { search, selectedTags } from '@stores/searchStore'; diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index a24784c..f6609a8 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -1,5 +1,6 @@ --- import { SITE_METADATA } from '@root/config'; +import { DetectThemeScript } from '@root/scripts'; export interface Props { title?: string | undefined; @@ -12,8 +13,8 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; - - + + @@ -22,4 +23,7 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; + + + diff --git a/src/components/ContactsList/ContactsList.astro b/src/components/ContactsList/ContactsList.astro index 08374b5..3ab3f95 100644 --- a/src/components/ContactsList/ContactsList.astro +++ b/src/components/ContactsList/ContactsList.astro @@ -11,14 +11,14 @@ const { diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index fdf366e..1426d4a 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -38,7 +38,7 @@ const { pathname } = Astro.canonicalURL; - + diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss index b3e246e..e890755 100644 --- a/src/components/Header/Header.scss +++ b/src/components/Header/Header.scss @@ -7,7 +7,6 @@ padding-bottom: 15px; user-select: none; z-index: 9999; - & .container { display: flex; align-items: center; @@ -64,57 +63,11 @@ } } } - &__button { - // cursor: pointer; - // background: none; - // border: none; - // &:hover { - // border: none; - // opacity: var(--opacity-hover); - // } - // & span { - // pointer-events: none; - // display: block; - // position: absolute; - // height: 3px; - // width: 100%; - // background: var(--font-color); - // border-radius: 7px; - // opacity: 1; - // left: 0; - // } - // & span:nth-child(1) { - // top: 2px; - // transform-origin: left center; - // } - // & span:nth-child(2) { - // top: 9px; - // transform-origin: left center; - // } - // & span:nth-child(3) { - // top: 16px; - // transform-origin: left center; - // } - // &[aria-pressed='true'] { - // & span:nth-child(1) { - // transform: rotate(45deg); - // top: -1px; - // left: 5px; - // } - // & span:nth-child(2) { - // display: none; - // } - // & span:nth-child(3) { - // transform: rotate(-45deg); - // top: 20px; - // left: 5px; - // } - // } - } } @media screen and (max-width: 768px) { .header { + padding: 10px 0; &__nav { display: none; } @@ -122,6 +75,7 @@ body[data-is-mobile-open='true'] { & .header { + padding: 15px 0; background-color: var(--background-header-color); position: fixed; right: 0; diff --git a/src/components/Header/NavToggle/NavToggle.scss b/src/components/Header/NavToggle/NavToggle.scss index 7ca42f4..9db71a9 100644 --- a/src/components/Header/NavToggle/NavToggle.scss +++ b/src/components/Header/NavToggle/NavToggle.scss @@ -1,9 +1,7 @@ .nav-toggle { - display: flex; - padding: 0; cursor: pointer; - // background: none; border: none; + padding: 0; &:hover { border: none; opacity: var(--opacity-hover); diff --git a/src/components/Header/NavToggle/NavToggle.tsx b/src/components/Header/NavToggle/NavToggle.tsx index e8ca43a..8af7531 100644 --- a/src/components/Header/NavToggle/NavToggle.tsx +++ b/src/components/Header/NavToggle/NavToggle.tsx @@ -4,19 +4,14 @@ import { createSignal, createEffect } from 'solid-js'; import './NavToggle.scss'; const MenuIcon: Component = () => ( - - + + ); const CloseIcon: Component = () => ( - - + + ); diff --git a/src/components/ProjectItem/ProjectItem.astro b/src/components/ProjectItem/ProjectItem.astro index a225f63..8c5bf74 100644 --- a/src/components/ProjectItem/ProjectItem.astro +++ b/src/components/ProjectItem/ProjectItem.astro @@ -1,6 +1,4 @@ --- -import type { ProjectType } from '@root/types'; - import './ProjectItem.scss'; import { Icon } from 'astro-icon'; diff --git a/src/components/RecentArticles/RecentArticles.astro b/src/components/RecentArticles/RecentArticles.astro index f495d37..8b5b7bc 100644 --- a/src/components/RecentArticles/RecentArticles.astro +++ b/src/components/RecentArticles/RecentArticles.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import './RecentArticles.scss'; import { ArticleItem } from '@components/ArticleItem'; import { sortArtcilesByDate } from '@utils/articles'; diff --git a/src/components/SearchInput/SearchInput.scss b/src/components/SearchInput/SearchInput.scss index a6ffffa..22fac36 100644 --- a/src/components/SearchInput/SearchInput.scss +++ b/src/components/SearchInput/SearchInput.scss @@ -20,7 +20,7 @@ & span { font-size: var(--font-size-lg); font-weight: 500; - color: var(--font-color-grayer); + color: var(--font-color-gray); min-width: 20px; text-align: center; } diff --git a/src/components/SearchInput/SearchInput.tsx b/src/components/SearchInput/SearchInput.tsx index d9ef696..9d0a8ad 100644 --- a/src/components/SearchInput/SearchInput.tsx +++ b/src/components/SearchInput/SearchInput.tsx @@ -54,7 +54,7 @@ const SearchInput: Component = (props) => { return (
- + diff --git a/src/components/SkillsBlock/SkillsBlock.astro b/src/components/SkillsBlock/SkillsBlock.astro index 7e91dec..66db2a3 100644 --- a/src/components/SkillsBlock/SkillsBlock.astro +++ b/src/components/SkillsBlock/SkillsBlock.astro @@ -1,6 +1,4 @@ --- -import type { SkillsType } from '@root/types'; - import { Icon } from 'astro-icon'; import './SkillsBlock.scss'; diff --git a/src/components/ThemeSwticher/ThemeSwitcher.astro b/src/components/ThemeSwticher/ThemeSwitcher.astro deleted file mode 100644 index 915d7c0..0000000 --- a/src/components/ThemeSwticher/ThemeSwitcher.astro +++ /dev/null @@ -1,8 +0,0 @@ ---- -import './ThemeSwitcher.scss'; -import { Icon } from 'astro-icon'; ---- - - diff --git a/src/components/ThemeSwticher/ThemeSwitcher.scss b/src/components/ThemeSwticher/ThemeSwitcher.scss index 2838418..7d7d4fa 100644 --- a/src/components/ThemeSwticher/ThemeSwitcher.scss +++ b/src/components/ThemeSwticher/ThemeSwitcher.scss @@ -6,8 +6,13 @@ cursor: pointer; padding: 0; margin: 0; + opacity: 0; &:hover { opacity: var(--opacity-hover); border: none; } + &.ready { + opacity: 1; + transition: all 0.1s linear 0s; + } } diff --git a/src/components/ThemeSwticher/ThemeSwitcher.tsx b/src/components/ThemeSwticher/ThemeSwitcher.tsx new file mode 100644 index 0000000..120fc20 --- /dev/null +++ b/src/components/ThemeSwticher/ThemeSwitcher.tsx @@ -0,0 +1,62 @@ +import type { Component, JSX } from 'solid-js'; + +import { SITE_SETTINGS } from '@root/config'; +import { createSignal, onMount, Switch, Match } from 'solid-js'; +import './ThemeSwitcher.scss'; + +const MoonIcon: Component = () => ( + + + +); + +const SunIcon: Component = () => ( + + + +); + +const ThemeSwitcher: Component = () => { + const [theme, setTheme] = createSignal(SITE_SETTINGS.defaultTheme); + const [isReady, setIsReady] = createSignal(false); + + const toggleTheme: JSX.EventHandler = (e) => { + const newTheme = theme() === 'light' ? 'dark' : 'light'; + setTheme(newTheme); + localStorage.setItem('theme', newTheme); + document.documentElement.setAttribute('data-theme', newTheme); + }; + + onMount(() => { + setIsReady(true); + if (window.theme) { + setTheme(window.theme); + /* Update theme state on changing OS the,e */ + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches: isDark }) => { + const theme = isDark ? 'dark' : 'light'; + setTheme(theme); + }); + } + }); + + return ( + + ); +}; + +export default ThemeSwitcher; diff --git a/src/components/ThemeSwticher/index.ts b/src/components/ThemeSwticher/index.ts index 50e6b3d..9b6b9ee 100644 --- a/src/components/ThemeSwticher/index.ts +++ b/src/components/ThemeSwticher/index.ts @@ -1 +1 @@ -export { default } from './ThemeSwitcher.astro'; +export { default } from './ThemeSwitcher'; diff --git a/src/config.ts b/src/config.ts index 4e46ed2..ad1320f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,7 @@ +export const SITE_SETTINGS: SiteConfigType = { + defaultTheme: 'dark', +}; + export const SITE_METADATA = { title: 'Sergey Yarkov', name: 'yarkov.tech', diff --git a/src/layouts/article.astro b/src/layouts/article.astro index 265b5a9..8306dce 100644 --- a/src/layouts/article.astro +++ b/src/layouts/article.astro @@ -1,6 +1,5 @@ --- import type { Props as BaseHeadProps } from '@root/components/BaseHead.astro'; -import type { ArticleType } from '@root/types'; import BaseHead from '@components/BaseHead.astro'; import BaseLayout from '@components/BaseLayout'; diff --git a/src/layouts/default.astro b/src/layouts/default.astro index 44ed720..304a553 100644 --- a/src/layouts/default.astro +++ b/src/layouts/default.astro @@ -1,9 +1,9 @@ --- import type { Props as BaseHeadProps } from '@components/BaseHead.astro'; +import { SITE_METADATA } from '@root/config'; import BaseHead from '@components/BaseHead.astro'; import BaseLayout from '@components/BaseLayout'; -import { SITE_METADATA } from '@root/config'; import PageHeading from '@components/PageHeading'; import '@styles/global.scss'; diff --git a/src/pages/articles.astro b/src/pages/articles.astro index 8735f7d..8f2974e 100644 --- a/src/pages/articles.astro +++ b/src/pages/articles.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import PageLayout from '@layouts/default.astro'; import ArticlesList from '@components/ArticlesList'; import { transformArticles, formatToArticleBlocks } from '@utils/articles'; diff --git a/src/pages/index.astro b/src/pages/index.astro index 9b474d6..df9c19a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import * as utils from '@utils/index'; import PageLayout from '@layouts/default.astro'; import RecentArticles from '@components/RecentArticles'; diff --git a/src/scripts/detect-theme.astro b/src/scripts/detect-theme.astro new file mode 100644 index 0000000..dddb31e --- /dev/null +++ b/src/scripts/detect-theme.astro @@ -0,0 +1,20 @@ + diff --git a/src/scripts/index.ts b/src/scripts/index.ts new file mode 100644 index 0000000..008a7dc --- /dev/null +++ b/src/scripts/index.ts @@ -0,0 +1 @@ +export { default as DetectThemeScript } from './detect-theme.astro'; diff --git a/src/styles/global.scss b/src/styles/global.scss index b6d7302..6bad530 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -1,91 +1,4 @@ -:root { - color-scheme: light dark; - - /* Fonts */ - --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; - --font-family-base: 'Rubik', var(--font-fallback); - --font-size-xs: 0.75rem; - --font-size-sm: 0.875rem; - --font-size-md: 1rem; - --font-size-lg: 1.125rem; - --font-size-xl: 1.25rem; - --font-size-2xl: 1.5rem; - --font-size-3xl: 1.875rem; - --font-size-4xl: 2.25rem; - --font-size-5xl: 3rem; - --font-size-6xl: 3.75rem; - --font-size-7xl: 4.5rem; - --font-size-8xl: 6rem; - --font-size-9xl: 8rem; - - /* Line heights */ - --line-height-normal: 'normal'; - --line-height-none: 1; - --line-height-shorter: 1.25; - --line-height-short: 1.375; - --line-height-base: 1.5; - --line-height-tall: 1.625; - - /* Colors */ - --color-white: #ffffff; - --color-black: #010409; - - --color-blue-50: #cae8ff; - --color-blue-100: #a5d6ff; - --color-blue-200: #79c0ff; - --color-blue-300: #58a6ff; - --color-blue-400: #388bfd; - --color-blue-500: #1f6feb; - --color-blue-600: #1158c7; - --color-blue-700: #0d419d; - --color-blue-800: #0c2d6b; - --color-blue-900: #051d4d; - - --color-gray-50: #f0f6fc; - --color-gray-100: #c9d1d9; - --color-gray-200: #b1bac4; - --color-gray-300: #8b949e; - --color-gray-400: #6e7681; - --color-gray-500: #484f58; - --color-gray-600: #30363d; - --color-gray-700: #21262d; - --color-gray-800: #161b22; - --color-gray-900: #0d1117; - - --color-orange-50: #ffdfb6; - --color-orange-100: #ffc680; - --color-orange-200: #ffa657; - --color-orange-300: #f0883e; - --color-orange-400: #db6d28; - --color-orange-500: #bd561d; - --color-orange-600: #9b4215; - --color-orange-700: #762d0a; - --color-orange-800: #5a1e02; - --color-orange-900: #3d1300; - - --color-yellow-50: #f8e3a1; - --color-yellow-100: #f2cc60; - --color-yellow-200: #e3b341; - --color-yellow-300: #d29922; - --color-yellow-400: #bb8009; - --color-yellow-500: #9e6a03; - --color-yellow-600: #845306; - --color-yellow-700: #693e00; - --color-yellow-800: #4b2900; - --color-yellow-900: #341a00; - - /* Border */ - --border-radius-md: 3px; - --border-radius-lg: 5px; - - /* Sizes */ - --content-width: 760px; - --content-padding: 24px; - - --outline-color: var(--color-blue-500); - - --opacity-hover: 0.7; -} +@import './theme.scss'; ::selection { background: var(--color-yellow-100); @@ -115,13 +28,14 @@ html { font-weight: normal; font-kerning: normal; font-family: var(--font-family-base); + background: var(--background-body-color); } body { margin: 0; padding: 0; color: var(--font-color); - background-color: var(--background-body-color); + background: var(--background-body-color); } .container { @@ -197,13 +111,14 @@ textarea { -webkit-appearance: none; font-family: var(--font-family-base); padding: 8px 15px; - border: 1px solid var(--border-color); + border: none; border-radius: var(--border-radius-md); background-color: var(--background-inputs-color); font-size: var(--font-size-sm); width: 100%; - outline-color: var(--outline-color); resize: vertical; + border: 1px solid var(--border-color); + outline-color: var(--color-blue-500); } button { @@ -249,12 +164,12 @@ pre { } a { - color: var(--color-blue-500); + color: var(--color-blue-400); font-weight: 500; text-decoration: none; &:hover { text-decoration: underline; - color: var(--color-blue-500); + color: var(--color-blue-400); } } diff --git a/src/styles/theme.scss b/src/styles/theme.scss new file mode 100644 index 0000000..9f13b2c --- /dev/null +++ b/src/styles/theme.scss @@ -0,0 +1,140 @@ +:root, +:root[data-theme='light'] { + color-scheme: light; + + /* Fonts */ + --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; + --font-family-base: 'Rubik', var(--font-fallback); + --font-size-xs: 0.75rem; + --font-size-sm: 0.875rem; + --font-size-md: 1rem; + --font-size-lg: 1.125rem; + --font-size-xl: 1.25rem; + --font-size-2xl: 1.5rem; + --font-size-3xl: 1.875rem; + --font-size-4xl: 2.25rem; + --font-size-5xl: 3rem; + --font-size-6xl: 3.75rem; + --font-size-7xl: 4.5rem; + --font-size-8xl: 6rem; + --font-size-9xl: 8rem; + + /* Line heights */ + --line-height-normal: 'normal'; + --line-height-none: 1; + --line-height-shorter: 1.25; + --line-height-short: 1.375; + --line-height-base: 1.5; + --line-height-tall: 1.625; + + /* Colors */ + --color-white: #ffffff; + --color-black: #010409; + + --color-blue-50: #cae8ff; + --color-blue-100: #a5d6ff; + --color-blue-200: #79c0ff; + --color-blue-300: #58a6ff; + --color-blue-400: #388bfd; + --color-blue-500: #1f6feb; + --color-blue-600: #1158c7; + --color-blue-700: #0d419d; + --color-blue-800: #0c2d6b; + --color-blue-900: #051d4d; + + --color-gray-50: #f0f6fc; + --color-gray-100: #c9d1d9; + --color-gray-200: #b1bac4; + --color-gray-300: #8b949e; + --color-gray-400: #6e7681; + --color-gray-500: #484f58; + --color-gray-600: #30363d; + --color-gray-700: #21262d; + --color-gray-800: #161b22; + --color-gray-900: #0d1117; + + --color-orange-50: #ffdfb6; + --color-orange-100: #ffc680; + --color-orange-200: #ffa657; + --color-orange-300: #f0883e; + --color-orange-400: #db6d28; + --color-orange-500: #bd561d; + --color-orange-600: #9b4215; + --color-orange-700: #762d0a; + --color-orange-800: #5a1e02; + --color-orange-900: #3d1300; + + --color-yellow-50: #f8e3a1; + --color-yellow-100: #f2cc60; + --color-yellow-200: #e3b341; + --color-yellow-300: #d29922; + --color-yellow-400: #bb8009; + --color-yellow-500: #9e6a03; + --color-yellow-600: #845306; + --color-yellow-700: #693e00; + --color-yellow-800: #4b2900; + --color-yellow-900: #341a00; + + /* Border */ + --border-radius-md: 3px; + --border-radius-lg: 5px; + + /* Sizes */ + --content-width: 760px; + --content-padding: 24px; + + --opacity-hover: 0.7; + + /* Fonts */ + --font-color: var(--color-black); + --font-color-gray: var(--color-gray-500); + --font-color-grayer: var(--color-gray-700); + + /* Border */ + --border-color: var(--color-gray-100); + --border-color-hover: var(--color-gray-400); + + /* Elements */ + --background-body-color: var(--color-white); + --background-header-color: var(--color-white); + --background-inline-code: rgba(0, 0, 0, 0.05); + --background-color-hover: var(--color-gray-50); + --background-btn-link: var(--color-white); + --background-btn-link-active: var(--color-white); + --background-inputs-color: var(--color-white); + + /* Icons */ + --icon-primary: var(--color-white); + --icon-secondary: var(--color-gray-700); +} + +:root[data-theme='dark'] { + color-scheme: dark; + /* Fonts */ + --font-color: var(--color-white); + --font-color-gray: var(--color-gray-100); + --font-color-grayer: var(--color-gray-200); + + /* Border */ + --border-color: var(--color-gray-700); + --border-color-hover: var(--color-gray-600); + + /* Elements */ + --background-body-color: var(--color-gray-900); + --background-header-color: var(--color-gray-900); + --background-inline-code: var(--color-gray-800); + --background-color-hover: var(--color-gray-800); + --background-btn-link: var(--color-gray-800); + --background-btn-link-active: var(--color-gray-700); + --background-inputs-color: var(--color-gray-800); + + /* Icons */ + --icon-primary: var(--color-white); + --icon-secondary: var(--color-gray-100); + --icon-filter: invert(100%); + + & .header svg, + & .site-content svg:not([data-filter='none']) { + filter: var(--icon-filter); + } +} diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index 91132d0..0000000 --- a/src/types/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export type ArticleType = { - title: string; - author: string; - tags: Array; - published_at: string; -}; - -export type ProjectType = { - icon: string; - name: string; - year: string; - description: string; - sourceUrl?: string | undefined; - articleUrl?: string | undefined; - demoUrl?: string | undefined; -}; - -export type SkillsType = { - title: string; - list: Array<{ icon?: string | undefined; name: string }>; -}; - -export type ArticleBlockType = { - [year: number]: ArticleType[]; -}; diff --git a/src/types/main.d.ts b/src/types/main.d.ts new file mode 100644 index 0000000..fa3ff37 --- /dev/null +++ b/src/types/main.d.ts @@ -0,0 +1,39 @@ +export {}; + +declare global { + interface Window { + theme?: ThemeModeType | undefined; + } + + type ArticleType = { + title: string; + author: string; + tags: Array; + published_at: string; + }; + + type ProjectType = { + icon: string; + name: string; + year: string; + description: string; + sourceUrl?: string | undefined; + articleUrl?: string | undefined; + demoUrl?: string | undefined; + }; + + type SkillsType = { + title: string; + list: Array<{ icon?: string | undefined; name: string }>; + }; + + type ArticleBlockType = { + [year: number]: ArticleType[]; + }; + + type ThemeModeType = 'light' | 'dark'; + + type SiteConfigType = { + defaultTheme: ThemeModeType; + }; +} diff --git a/src/utils/articles.ts b/src/utils/articles.ts index f63124b..845d8b6 100644 --- a/src/utils/articles.ts +++ b/src/utils/articles.ts @@ -1,5 +1,3 @@ -import type { ArticleType, ArticleBlockType } from '@root/types'; - import { MarkdownInstance } from 'astro'; export const transformArticles = (articles: MarkdownInstance[]): ArticleType[] => diff --git a/tsconfig.json b/tsconfig.json index 9adedda..cdc34f0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "@utils/*": ["./src/utils/*"], "@stores/*": ["./src/stores/*"] }, - "outDir": "./dist" + "outDir": "./dist", + "typeRoots": ["./node_modules/@types", "./src/types"] }, "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts"] }