mirror of
https://github.com/sergeyyarkov/yarkov.tech.git
synced 2026-10-11 18:39:14 +03:00
theme toggling
This commit is contained in:
parent
5f76f318db
commit
75fa8117f6
@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev --host",
|
"dev": "astro dev --host",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro check && tsc --noEmit && astro build",
|
||||||
"preview": "astro preview --host",
|
"preview": "astro preview --host",
|
||||||
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json}\"",
|
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json}\"",
|
||||||
"lint": "eslint '**/*.{js,mjs,ts,tsx}'"
|
"lint": "eslint '**/*.{js,mjs,ts,tsx}'"
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
@ -1,8 +1,6 @@
|
|||||||
import type { ArticleType } from '@root/types';
|
|
||||||
|
|
||||||
import './ArticleItem.scss';
|
|
||||||
import { Component } from 'solid-js';
|
import { Component } from 'solid-js';
|
||||||
import { DateFormatter } from '@utils/date';
|
import { DateFormatter } from '@utils/date';
|
||||||
|
import './ArticleItem.scss';
|
||||||
|
|
||||||
export type ArticleItemProps = {
|
export type ArticleItemProps = {
|
||||||
data: ArticleType;
|
data: ArticleType;
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
import type { ArticleType } from '@root/types';
|
|
||||||
|
|
||||||
import { DateFormatter } from '@root/utils';
|
import { DateFormatter } from '@root/utils';
|
||||||
import './ArticlePost.scss';
|
import './ArticlePost.scss';
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import type { Component } from 'solid-js';
|
import type { Component } from 'solid-js';
|
||||||
import type { ArticleBlockType } from '@root/types';
|
|
||||||
|
|
||||||
import { createSignal, createEffect, For } from 'solid-js';
|
import { createSignal, createEffect, For } from 'solid-js';
|
||||||
import { search, selectedTags } from '@stores/searchStore';
|
import { search, selectedTags } from '@stores/searchStore';
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
import { SITE_METADATA } from '@root/config';
|
import { SITE_METADATA } from '@root/config';
|
||||||
|
import { DetectThemeScript } from '@root/scripts';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title?: string | undefined;
|
title?: string | undefined;
|
||||||
@ -12,8 +13,8 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props;
|
|||||||
<link rel='preconnect' href='https://fonts.googleapis.com' />
|
<link rel='preconnect' href='https://fonts.googleapis.com' />
|
||||||
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin />
|
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin />
|
||||||
<link href='https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap' rel='stylesheet' />
|
<link href='https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap' rel='stylesheet' />
|
||||||
<link rel='stylesheet' href='assets/dark.css' media='(prefers-color-scheme: dark)' />
|
<!-- <link rel='stylesheet' href='assets/dark.css' media='(prefers-color-scheme: dark)' /> -->
|
||||||
<link rel='stylesheet' href='assets/light.css' media='(prefers-color-scheme: light)' />
|
<!-- <link rel='stylesheet' href='assets/light.css' media='(prefers-color-scheme: light)' /> -->
|
||||||
|
|
||||||
<meta charset='utf-8' />
|
<meta charset='utf-8' />
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||||
@ -22,4 +23,7 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props;
|
|||||||
</title>
|
</title>
|
||||||
<meta name='title' content={title} />
|
<meta name='title' content={title} />
|
||||||
<meta name='description' content={description || SITE_METADATA.description} />
|
<meta name='description' content={description || SITE_METADATA.description} />
|
||||||
|
|
||||||
|
<!-- This script will prevent FOUC -->
|
||||||
|
<DetectThemeScript />
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|||||||
@ -11,14 +11,14 @@ const {
|
|||||||
<div class='contacts-list'>
|
<div class='contacts-list'>
|
||||||
<a href={'mailto:' + email}
|
<a href={'mailto:' + email}
|
||||||
>Email
|
>Email
|
||||||
<Icon name='arrow-up-right' width='15' height='15' />
|
<Icon name='arrow-up-right' width='15' height='15' data-filter='none' />
|
||||||
</a>
|
</a>
|
||||||
<a href={githubUrl} target='_blank'
|
<a href={githubUrl} target='_blank'
|
||||||
>Github
|
>Github
|
||||||
<Icon name='arrow-up-right' width='15' height='15' />
|
<Icon name='arrow-up-right' width='15' height='15' data-filter='none' />
|
||||||
</a>
|
</a>
|
||||||
<a href={telegramUrl} target='_blank'
|
<a href={telegramUrl} target='_blank'
|
||||||
>Telegram
|
>Telegram
|
||||||
<Icon name='arrow-up-right' width='15' height='15' />
|
<Icon name='arrow-up-right' width='15' height='15' data-filter='none' />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -38,7 +38,7 @@ const { pathname } = Astro.canonicalURL;
|
|||||||
<Icon name='telegram' width='18' height='18' />
|
<Icon name='telegram' width='18' height='18' />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ThemeSwitcher />
|
<ThemeSwitcher client:load />
|
||||||
</nav>
|
</nav>
|
||||||
<NavToggle client:visible />
|
<NavToggle client:visible />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
|
||||||
& .container {
|
& .container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
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) {
|
@media screen and (max-width: 768px) {
|
||||||
.header {
|
.header {
|
||||||
|
padding: 10px 0;
|
||||||
&__nav {
|
&__nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -122,6 +75,7 @@
|
|||||||
|
|
||||||
body[data-is-mobile-open='true'] {
|
body[data-is-mobile-open='true'] {
|
||||||
& .header {
|
& .header {
|
||||||
|
padding: 15px 0;
|
||||||
background-color: var(--background-header-color);
|
background-color: var(--background-header-color);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
.nav-toggle {
|
.nav-toggle {
|
||||||
display: flex;
|
|
||||||
padding: 0;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
// background: none;
|
|
||||||
border: none;
|
border: none;
|
||||||
|
padding: 0;
|
||||||
&:hover {
|
&:hover {
|
||||||
border: none;
|
border: none;
|
||||||
opacity: var(--opacity-hover);
|
opacity: var(--opacity-hover);
|
||||||
|
|||||||
@ -4,19 +4,14 @@ import { createSignal, createEffect } from 'solid-js';
|
|||||||
import './NavToggle.scss';
|
import './NavToggle.scss';
|
||||||
|
|
||||||
const MenuIcon: Component = () => (
|
const MenuIcon: Component = () => (
|
||||||
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="24px" height="24px">
|
||||||
<path d="M21 6V8H3V6H21ZM3 18H21V16H3V18ZM3 13H21V11H3V13Z" fill="black" />
|
<path d="M 0 7.5 L 0 12.5 L 50 12.5 L 50 7.5 Z M 0 22.5 L 0 27.5 L 50 27.5 L 50 22.5 Z M 0 37.5 L 0 42.5 L 50 42.5 L 50 37.5 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
const CloseIcon: Component = () => (
|
const CloseIcon: Component = () => (
|
||||||
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="24px" height="24px">
|
||||||
<path
|
<path d="M 9.15625 6.3125 L 6.3125 9.15625 L 22.15625 25 L 6.21875 40.96875 L 9.03125 43.78125 L 25 27.84375 L 40.9375 43.78125 L 43.78125 40.9375 L 27.84375 25 L 43.6875 9.15625 L 40.84375 6.3125 L 25 22.15625 Z" />
|
||||||
fill-rule="evenodd"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
d="M12.0002 13.0605L17.4692 18.531L18.5312 17.4705L13.0607 12L18.5312 6.53099L17.4707 5.46899L12.0002 10.9395L6.5312 5.46899L5.4707 6.53099L10.9397 12L5.4707 17.469L6.5312 18.531L12.0002 13.0605Z"
|
|
||||||
fill="black"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
import type { ProjectType } from '@root/types';
|
|
||||||
|
|
||||||
import './ProjectItem.scss';
|
import './ProjectItem.scss';
|
||||||
import { Icon } from 'astro-icon';
|
import { Icon } from 'astro-icon';
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
import type { ArticleType } from '@root/types';
|
|
||||||
|
|
||||||
import './RecentArticles.scss';
|
import './RecentArticles.scss';
|
||||||
import { ArticleItem } from '@components/ArticleItem';
|
import { ArticleItem } from '@components/ArticleItem';
|
||||||
import { sortArtcilesByDate } from '@utils/articles';
|
import { sortArtcilesByDate } from '@utils/articles';
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
& span {
|
& span {
|
||||||
font-size: var(--font-size-lg);
|
font-size: var(--font-size-lg);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--font-color-grayer);
|
color: var(--font-color-gray);
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,7 +54,7 @@ const SearchInput: Component<SearchInputProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="search-input">
|
<div class="search-input">
|
||||||
<svg width="25" height="24" viewBox="0 0 25 24" xmlns="http://www.w3.org/2000/svg">
|
<svg width="25" height="24" viewBox="0 0 25 24" xmlns="http://www.w3.org/2000/svg" data-filter="none">
|
||||||
<path d="M10.6026 3.60001C11.8798 3.59993 13.1316 3.94283 14.2172 4.5901C15.3028 5.23736 16.179 6.16331 16.7472 7.26368C17.3154 8.36405 17.5531 9.59517 17.4334 10.8184C17.3137 12.0417 16.8415 13.2085 16.0699 14.1876L21.2427 19.164C21.4085 19.3248 21.5053 19.5399 21.5135 19.7662C21.5218 19.9926 21.4411 20.2137 21.2874 20.3853C21.1337 20.5569 20.9184 20.6665 20.6845 20.6921C20.4505 20.7178 20.2151 20.6576 20.0253 20.5236L19.9205 20.436L14.7476 15.4596C13.8802 16.0922 12.8687 16.5172 11.7968 16.6994C10.7248 16.8815 9.62324 16.8157 8.58298 16.5074C7.54272 16.199 6.59366 15.6569 5.81422 14.9259C5.03478 14.1949 4.44733 13.296 4.10042 12.3034C3.7535 11.3108 3.65708 10.2531 3.81911 9.21757C3.98114 8.18204 4.39698 7.19847 5.03226 6.34812C5.66755 5.49778 6.50404 4.80506 7.47263 4.32721C8.44122 3.84936 9.51411 3.60009 10.6026 3.60001V3.60001ZM10.6026 5.40001C9.27934 5.40001 8.01025 5.90572 7.07454 6.80589C6.13884 7.70607 5.61316 8.92697 5.61316 10.2C5.61316 11.473 6.13884 12.6939 7.07454 13.5941C8.01025 14.4943 9.27934 15 10.6026 15C11.9259 15 13.195 14.4943 14.1307 13.5941C15.0664 12.6939 15.5921 11.473 15.5921 10.2C15.5921 8.92697 15.0664 7.70607 14.1307 6.80589C13.195 5.90572 11.9259 5.40001 10.6026 5.40001Z" />
|
<path d="M10.6026 3.60001C11.8798 3.59993 13.1316 3.94283 14.2172 4.5901C15.3028 5.23736 16.179 6.16331 16.7472 7.26368C17.3154 8.36405 17.5531 9.59517 17.4334 10.8184C17.3137 12.0417 16.8415 13.2085 16.0699 14.1876L21.2427 19.164C21.4085 19.3248 21.5053 19.5399 21.5135 19.7662C21.5218 19.9926 21.4411 20.2137 21.2874 20.3853C21.1337 20.5569 20.9184 20.6665 20.6845 20.6921C20.4505 20.7178 20.2151 20.6576 20.0253 20.5236L19.9205 20.436L14.7476 15.4596C13.8802 16.0922 12.8687 16.5172 11.7968 16.6994C10.7248 16.8815 9.62324 16.8157 8.58298 16.5074C7.54272 16.199 6.59366 15.6569 5.81422 14.9259C5.03478 14.1949 4.44733 13.296 4.10042 12.3034C3.7535 11.3108 3.65708 10.2531 3.81911 9.21757C3.98114 8.18204 4.39698 7.19847 5.03226 6.34812C5.66755 5.49778 6.50404 4.80506 7.47263 4.32721C8.44122 3.84936 9.51411 3.60009 10.6026 3.60001V3.60001ZM10.6026 5.40001C9.27934 5.40001 8.01025 5.90572 7.07454 6.80589C6.13884 7.70607 5.61316 8.92697 5.61316 10.2C5.61316 11.473 6.13884 12.6939 7.07454 13.5941C8.01025 14.4943 9.27934 15 10.6026 15C11.9259 15 13.195 14.4943 14.1307 13.5941C15.0664 12.6939 15.5921 11.473 15.5921 10.2C15.5921 8.92697 15.0664 7.70607 14.1307 6.80589C13.195 5.90572 11.9259 5.40001 10.6026 5.40001Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<input onInput={onSearch} value={search()} type="text" placeholder={props.placeholder || 'Search article by title or description...'} />
|
<input onInput={onSearch} value={search()} type="text" placeholder={props.placeholder || 'Search article by title or description...'} />
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
import type { SkillsType } from '@root/types';
|
|
||||||
|
|
||||||
import { Icon } from 'astro-icon';
|
import { Icon } from 'astro-icon';
|
||||||
import './SkillsBlock.scss';
|
import './SkillsBlock.scss';
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
import './ThemeSwitcher.scss';
|
|
||||||
import { Icon } from 'astro-icon';
|
|
||||||
---
|
|
||||||
|
|
||||||
<button class='theme-switcher'>
|
|
||||||
<Icon name='moon' width='21' height='21' />
|
|
||||||
</button>
|
|
||||||
@ -6,8 +6,13 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
opacity: 0;
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: var(--opacity-hover);
|
opacity: var(--opacity-hover);
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
&.ready {
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.1s linear 0s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
62
src/components/ThemeSwticher/ThemeSwitcher.tsx
Normal file
62
src/components/ThemeSwticher/ThemeSwitcher.tsx
Normal file
@ -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 = () => (
|
||||||
|
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M10.4998 10.3311C9.39883 9.22975 8.64906 7.82674 8.34521 6.29939C8.04136 4.77203 8.19707 3.18889 8.79266 1.75C7.09451 2.08429 5.53468 2.91752 4.31266 4.14313C0.895781 7.56 0.895781 13.1005 4.31266 16.5174C7.73041 19.9351 13.27 19.9342 16.6878 16.5174C17.9131 15.2955 18.7462 13.736 19.0809 12.0382C17.642 12.6337 16.0589 12.7894 14.5316 12.4855C13.0042 12.1817 11.6012 11.432 10.4998 10.3311Z"
|
||||||
|
fill="#010409"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const SunIcon: Component = () => (
|
||||||
|
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M6.12062 10.5C6.12062 12.9159 8.08587 14.8811 10.5017 14.8811C12.9176 14.8811 14.8829 12.9159 14.8829 10.5C14.8829 8.08413 12.9176 6.11888 10.5017 6.11888C8.08587 6.11888 6.12062 8.08413 6.12062 10.5ZM9.625 16.625H11.375V19.25H9.625V16.625ZM9.625 1.75H11.375V4.375H9.625V1.75ZM1.75 9.625H4.375V11.375H1.75V9.625ZM16.625 9.625H19.25V11.375H16.625V9.625ZM4.93238 17.3057L3.69513 16.0685L5.551 14.2126L6.78825 15.4499L4.93238 17.3057ZM14.2118 5.551L16.0685 3.69425L17.3057 4.9315L15.449 6.78825L14.2118 5.551ZM5.551 6.78912L3.69513 4.93238L4.93325 3.69513L6.78825 5.55187L5.551 6.78912ZM17.3057 16.0685L16.0685 17.3057L14.2118 15.449L15.449 14.2118L17.3057 16.0685Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const ThemeSwitcher: Component = () => {
|
||||||
|
const [theme, setTheme] = createSignal<ThemeModeType>(SITE_SETTINGS.defaultTheme);
|
||||||
|
const [isReady, setIsReady] = createSignal<boolean>(false);
|
||||||
|
|
||||||
|
const toggleTheme: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (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 (
|
||||||
|
<button onClick={toggleTheme} class={isReady() ? 'theme-switcher ready' : 'theme-switcher'}>
|
||||||
|
<Switch
|
||||||
|
children={
|
||||||
|
<>
|
||||||
|
<Match when={theme() === 'light'} children={<MoonIcon />} />
|
||||||
|
<Match when={theme() === 'dark'} children={<SunIcon />} />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ThemeSwitcher;
|
||||||
@ -1 +1 @@
|
|||||||
export { default } from './ThemeSwitcher.astro';
|
export { default } from './ThemeSwitcher';
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
export const SITE_SETTINGS: SiteConfigType = {
|
||||||
|
defaultTheme: 'dark',
|
||||||
|
};
|
||||||
|
|
||||||
export const SITE_METADATA = {
|
export const SITE_METADATA = {
|
||||||
title: 'Sergey Yarkov',
|
title: 'Sergey Yarkov',
|
||||||
name: 'yarkov.tech',
|
name: 'yarkov.tech',
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
---
|
---
|
||||||
import type { Props as BaseHeadProps } from '@root/components/BaseHead.astro';
|
import type { Props as BaseHeadProps } from '@root/components/BaseHead.astro';
|
||||||
import type { ArticleType } from '@root/types';
|
|
||||||
|
|
||||||
import BaseHead from '@components/BaseHead.astro';
|
import BaseHead from '@components/BaseHead.astro';
|
||||||
import BaseLayout from '@components/BaseLayout';
|
import BaseLayout from '@components/BaseLayout';
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
import type { Props as BaseHeadProps } from '@components/BaseHead.astro';
|
import type { Props as BaseHeadProps } from '@components/BaseHead.astro';
|
||||||
|
|
||||||
|
import { SITE_METADATA } from '@root/config';
|
||||||
import BaseHead from '@components/BaseHead.astro';
|
import BaseHead from '@components/BaseHead.astro';
|
||||||
import BaseLayout from '@components/BaseLayout';
|
import BaseLayout from '@components/BaseLayout';
|
||||||
import { SITE_METADATA } from '@root/config';
|
|
||||||
import PageHeading from '@components/PageHeading';
|
import PageHeading from '@components/PageHeading';
|
||||||
import '@styles/global.scss';
|
import '@styles/global.scss';
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
import type { ArticleType } from '@root/types';
|
|
||||||
|
|
||||||
import PageLayout from '@layouts/default.astro';
|
import PageLayout from '@layouts/default.astro';
|
||||||
import ArticlesList from '@components/ArticlesList';
|
import ArticlesList from '@components/ArticlesList';
|
||||||
import { transformArticles, formatToArticleBlocks } from '@utils/articles';
|
import { transformArticles, formatToArticleBlocks } from '@utils/articles';
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
import type { ArticleType } from '@root/types';
|
|
||||||
|
|
||||||
import * as utils from '@utils/index';
|
import * as utils from '@utils/index';
|
||||||
import PageLayout from '@layouts/default.astro';
|
import PageLayout from '@layouts/default.astro';
|
||||||
import RecentArticles from '@components/RecentArticles';
|
import RecentArticles from '@components/RecentArticles';
|
||||||
|
|||||||
20
src/scripts/detect-theme.astro
Normal file
20
src/scripts/detect-theme.astro
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script is:inline>
|
||||||
|
const THEME_STORAGE_KEY = 'theme';
|
||||||
|
|
||||||
|
const getTheme = () => {
|
||||||
|
const local = localStorage.getItem(THEME_STORAGE_KEY);
|
||||||
|
if (local && (local === 'dark' || local === 'light')) return local;
|
||||||
|
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
return isDark ? 'dark' : 'light';
|
||||||
|
};
|
||||||
|
|
||||||
|
window.theme = getTheme();
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
|
||||||
|
/* Sync with OS theme */
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches: isDark }) => {
|
||||||
|
window.theme = isDark ? 'dark' : 'light';
|
||||||
|
localStorage.setItem(THEME_STORAGE_KEY, theme);
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
1
src/scripts/index.ts
Normal file
1
src/scripts/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as DetectThemeScript } from './detect-theme.astro';
|
||||||
@ -1,91 +1,4 @@
|
|||||||
:root {
|
@import './theme.scss';
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--color-yellow-100);
|
background: var(--color-yellow-100);
|
||||||
@ -115,13 +28,14 @@ html {
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-kerning: normal;
|
font-kerning: normal;
|
||||||
font-family: var(--font-family-base);
|
font-family: var(--font-family-base);
|
||||||
|
background: var(--background-body-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
color: var(--font-color);
|
color: var(--font-color);
|
||||||
background-color: var(--background-body-color);
|
background: var(--background-body-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@ -197,13 +111,14 @@ textarea {
|
|||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
font-family: var(--font-family-base);
|
font-family: var(--font-family-base);
|
||||||
padding: 8px 15px;
|
padding: 8px 15px;
|
||||||
border: 1px solid var(--border-color);
|
border: none;
|
||||||
border-radius: var(--border-radius-md);
|
border-radius: var(--border-radius-md);
|
||||||
background-color: var(--background-inputs-color);
|
background-color: var(--background-inputs-color);
|
||||||
font-size: var(--font-size-sm);
|
font-size: var(--font-size-sm);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
outline-color: var(--outline-color);
|
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
outline-color: var(--color-blue-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@ -249,12 +164,12 @@ pre {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--color-blue-500);
|
color: var(--color-blue-400);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
color: var(--color-blue-500);
|
color: var(--color-blue-400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
140
src/styles/theme.scss
Normal file
140
src/styles/theme.scss
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,25 +0,0 @@
|
|||||||
export type ArticleType = {
|
|
||||||
title: string;
|
|
||||||
author: string;
|
|
||||||
tags: Array<string>;
|
|
||||||
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[];
|
|
||||||
};
|
|
||||||
39
src/types/main.d.ts
vendored
Normal file
39
src/types/main.d.ts
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
export {};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
theme?: ThemeModeType | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticleType = {
|
||||||
|
title: string;
|
||||||
|
author: string;
|
||||||
|
tags: Array<string>;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,5 +1,3 @@
|
|||||||
import type { ArticleType, ArticleBlockType } from '@root/types';
|
|
||||||
|
|
||||||
import { MarkdownInstance } from 'astro';
|
import { MarkdownInstance } from 'astro';
|
||||||
|
|
||||||
export const transformArticles = (articles: MarkdownInstance<ArticleType>[]): ArticleType[] =>
|
export const transformArticles = (articles: MarkdownInstance<ArticleType>[]): ArticleType[] =>
|
||||||
|
|||||||
@ -17,7 +17,8 @@
|
|||||||
"@utils/*": ["./src/utils/*"],
|
"@utils/*": ["./src/utils/*"],
|
||||||
"@stores/*": ["./src/stores/*"]
|
"@stores/*": ["./src/stores/*"]
|
||||||
},
|
},
|
||||||
"outDir": "./dist"
|
"outDir": "./dist",
|
||||||
|
"typeRoots": ["./node_modules/@types", "./src/types"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts"]
|
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user