Don't use tabs in editor

This commit is contained in:
prototypa
2023-01-09 21:44:06 -05:00
parent 58484dfca8
commit f641767078
56 changed files with 2217 additions and 2203 deletions

View File

@ -3,117 +3,117 @@ import { SITE } from '~/config.mjs';
---
<script is:inline define:vars={{ defaultTheme: SITE.defaultTheme }}>
function applyTheme(theme) {
if (theme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
function applyTheme(theme) {
if (theme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
if ((defaultTheme && defaultTheme.endsWith(':only')) || (!localStorage.theme && defaultTheme !== 'system')) {
applyTheme(defaultTheme.replace(':only', ''));
} else if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
applyTheme('dark');
} else {
applyTheme('light');
}
if ((defaultTheme && defaultTheme.endsWith(':only')) || (!localStorage.theme && defaultTheme !== 'system')) {
applyTheme(defaultTheme.replace(':only', ''));
} else if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
applyTheme('dark');
} else {
applyTheme('light');
}
function attachEvent(selector, event, fn) {
const matches = typeof selector === 'string' ? document.querySelectorAll(selector) : selector;
if (matches && matches.length) {
matches.forEach((elem) => {
elem.addEventListener(event, (e) => fn(e, elem), false);
});
}
}
function attachEvent(selector, event, fn) {
const matches = typeof selector === 'string' ? document.querySelectorAll(selector) : selector;
if (matches && matches.length) {
matches.forEach((elem) => {
elem.addEventListener(event, (e) => fn(e, elem), false);
});
}
}
window.onload = function () {
let lastKnownScrollPosition = window.scrollY;
let ticking = true;
window.onload = function () {
let lastKnownScrollPosition = window.scrollY;
let ticking = true;
attachEvent('[data-aw-toggle-menu]', 'click', function (_, elem) {
elem.classList.toggle('expanded');
document.body.classList.toggle('overflow-hidden');
document.getElementById('header')?.classList.toggle('h-screen');
document.querySelector('#header nav')?.classList.toggle('hidden');
});
attachEvent('[data-aw-toggle-menu]', 'click', function (_, elem) {
elem.classList.toggle('expanded');
document.body.classList.toggle('overflow-hidden');
document.getElementById('header')?.classList.toggle('h-screen');
document.querySelector('#header nav')?.classList.toggle('hidden');
});
attachEvent('[data-aw-toggle-color-scheme]', 'click', function () {
if (defaultTheme.endsWith(':only')) {
return;
}
document.documentElement.classList.toggle('dark');
localStorage.theme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
});
attachEvent('[data-aw-toggle-color-scheme]', 'click', function () {
if (defaultTheme.endsWith(':only')) {
return;
}
document.documentElement.classList.toggle('dark');
localStorage.theme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
});
attachEvent('[data-aw-social-share]', 'click', function (_, elem) {
const network = elem.getAttribute('data-aw-social-share');
const url = encodeURIComponent(elem.getAttribute('data-aw-url'));
const text = encodeURIComponent(elem.getAttribute('data-aw-text'));
attachEvent('[data-aw-social-share]', 'click', function (_, elem) {
const network = elem.getAttribute('data-aw-social-share');
const url = encodeURIComponent(elem.getAttribute('data-aw-url'));
const text = encodeURIComponent(elem.getAttribute('data-aw-text'));
let href;
switch (network) {
case 'facebook':
href = `https://www.facebook.com/sharer.php?u=${url}`;
break;
case 'twitter':
href = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
break;
case 'linkedin':
href = `https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${text}`;
break;
case 'whatsapp':
href = `https://wa.me/?text=${text}%20${url}`;
break;
case 'mail':
href = `mailto:?subject=%22${text}%22&body=${text}%20${url}`;
break;
let href;
switch (network) {
case 'facebook':
href = `https://www.facebook.com/sharer.php?u=${url}`;
break;
case 'twitter':
href = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
break;
case 'linkedin':
href = `https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${text}`;
break;
case 'whatsapp':
href = `https://wa.me/?text=${text}%20${url}`;
break;
case 'mail':
href = `mailto:?subject=%22${text}%22&body=${text}%20${url}`;
break;
default:
return;
}
default:
return;
}
const newlink = document.createElement('a');
newlink.target = '_blank';
newlink.href = href;
newlink.click();
});
const newlink = document.createElement('a');
newlink.target = '_blank';
newlink.href = href;
newlink.click();
});
function appyHeaderStylesOnScroll() {
const header = document.getElementById('header');
if (lastKnownScrollPosition > 60 && !header.classList.contains('scroll')) {
document.getElementById('header').classList.add('scroll');
} else if (lastKnownScrollPosition <= 60 && header.classList.contains('scroll')) {
document.getElementById('header').classList.remove('scroll');
}
ticking = false;
}
appyHeaderStylesOnScroll();
function appyHeaderStylesOnScroll() {
const header = document.getElementById('header');
if (lastKnownScrollPosition > 60 && !header.classList.contains('scroll')) {
document.getElementById('header').classList.add('scroll');
} else if (lastKnownScrollPosition <= 60 && header.classList.contains('scroll')) {
document.getElementById('header').classList.remove('scroll');
}
ticking = false;
}
appyHeaderStylesOnScroll();
attachEvent([document], 'scroll', function () {
lastKnownScrollPosition = window.scrollY;
attachEvent([document], 'scroll', function () {
lastKnownScrollPosition = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(() => {
appyHeaderStylesOnScroll();
});
ticking = true;
}
});
};
if (!ticking) {
window.requestAnimationFrame(() => {
appyHeaderStylesOnScroll();
});
ticking = true;
}
});
};
window.onpageshow = function () {
document.documentElement.classList.add('motion-safe:scroll-smooth');
const elem = document.querySelector('[data-aw-toggle-menu]');
if (elem) {
elem.classList.remove('expanded');
}
document.body.classList.remove('overflow-hidden');
document.getElementById('header')?.classList.remove('h-screen');
document.querySelector('#header nav')?.classList.add('hidden');
};
window.onpageshow = function () {
document.documentElement.classList.add('motion-safe:scroll-smooth');
const elem = document.querySelector('[data-aw-toggle-menu]');
if (elem) {
elem.classList.remove('expanded');
}
document.body.classList.remove('overflow-hidden');
document.getElementById('header')?.classList.remove('h-screen');
document.querySelector('#header nav')?.classList.add('hidden');
};
</script>

View File

@ -2,5 +2,5 @@
---
<span class="self-center ml-2 text-2xl md:text-xl font-bold text-gray-900 whitespace-nowrap dark:text-white">
🚀 AstroWind</span
🚀 AstroWind</span
>

View File

@ -12,74 +12,74 @@ import Fonts from '~/components/common/Fonts.astro';
import SplitbeeAnalytics from './SplitbeeAnalytics.astro';
export interface Props extends MetaSEO {
dontUseTitleTemplate?: boolean;
dontUseTitleTemplate?: boolean;
}
const defaultImage = SITE.defaultImage
? (
await getImage({
src: SITE.defaultImage,
alt: 'Default image',
width: 1200,
height: 628,
})
).src
: '';
? (
await getImage({
src: SITE.defaultImage,
alt: 'Default image',
width: 1200,
height: 628,
})
).src
: '';
const {
title = SITE.name,
description = '',
image: _image = defaultImage,
title = SITE.name,
description = '',
image: _image = defaultImage,
canonical = getCanonical(String(Astro.url.pathname)),
noindex = false,
nofollow = false,
canonical = getCanonical(String(Astro.url.pathname)),
noindex = false,
nofollow = false,
ogTitle = title,
ogType = 'website',
ogTitle = title,
ogType = 'website',
dontUseTitleTemplate = false,
dontUseTitleTemplate = false,
} = Astro.props;
const image =
typeof _image === 'string'
? new URL(_image, Astro.site)
: _image && typeof _image['src'] !== 'undefined'
? // @ts-ignore
new URL(getRelativeUrlByFilePath(_image.src), Astro.site)
: null;
typeof _image === 'string'
? new URL(_image, Astro.site)
: _image && typeof _image['src'] !== 'undefined'
? // @ts-ignore
new URL(getRelativeUrlByFilePath(_image.src), Astro.site)
: null;
---
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<AstroSeo
title={title}
titleTemplate={dontUseTitleTemplate ? '%s' : `%s — ${SITE.name}`}
description={description}
canonical={String(canonical)}
noindex={noindex}
nofollow={nofollow}
openGraph={{
url: String(canonical),
title: ogTitle,
description: description,
type: ogType,
images: image
? [
{
url: image.toString(),
alt: ogTitle,
},
]
: undefined,
// site_name: 'SiteName',
}}
twitter={{
// handle: '@handle',
// site: '@site',
cardType: image ? 'summary_large_image' : undefined,
}}
title={title}
titleTemplate={dontUseTitleTemplate ? '%s' : `%s — ${SITE.name}`}
description={description}
canonical={String(canonical)}
noindex={noindex}
nofollow={nofollow}
openGraph={{
url: String(canonical),
title: ogTitle,
description: description,
type: ogType,
images: image
? [
{
url: image.toString(),
alt: ogTitle,
},
]
: undefined,
// site_name: 'SiteName',
}}
twitter={{
// handle: '@handle',
// site: '@site',
cardType: image ? 'summary_large_image' : undefined,
}}
/>
<Fonts />

View File

@ -3,32 +3,32 @@ import { Icon } from 'astro-icon';
import { getPermalink } from '~/utils/permalinks';
export interface Props {
prevUrl: string;
nextUrl: string;
prevText?: string;
nextText?: string;
prevUrl: string;
nextUrl: string;
prevText?: string;
nextText?: string;
}
const { prevUrl, nextUrl, prevText = 'Newer posts', nextText = 'Older posts' } = Astro.props;
---
{
(prevUrl || nextUrl) && (
<div class="container flex">
<div class="flex flex-row mx-auto container justify-between">
<a href={getPermalink(prevUrl)} class={`btn btn-ghost px-3 mr-2 ${!prevUrl ? 'invisible' : ''}`}>
<div class="flex flex-row align-middle">
<Icon name="tabler:chevron-left" class="w-6 h-6" />
<p class="ml-2">{prevText}</p>
</div>
</a>
<a href={getPermalink(nextUrl)} class={`btn btn-ghost px-3 ${!nextUrl ? 'invisible' : ''}`}>
<div class="flex flex-row align-middle">
<span class="mr-2">{nextText}</span>
<Icon name="tabler:chevron-right" class="w-6 h-6" />
</div>
</a>
</div>
</div>
)
(prevUrl || nextUrl) && (
<div class="container flex">
<div class="flex flex-row mx-auto container justify-between">
<a href={getPermalink(prevUrl)} class={`btn btn-ghost px-3 mr-2 ${!prevUrl ? 'invisible' : ''}`}>
<div class="flex flex-row align-middle">
<Icon name="tabler:chevron-left" class="w-6 h-6" />
<p class="ml-2">{prevText}</p>
</div>
</a>
<a href={getPermalink(nextUrl)} class={`btn btn-ghost px-3 ${!nextUrl ? 'invisible' : ''}`}>
<div class="flex flex-row align-middle">
<span class="mr-2">{nextText}</span>
<Icon name="tabler:chevron-right" class="w-6 h-6" />
</div>
</a>
</div>
</div>
)
}

View File

@ -2,29 +2,29 @@
import { Icon } from 'astro-icon';
export interface Props {
text: string;
url: string | URL;
class?: string;
text: string;
url: string | URL;
class?: string;
}
const { text, url, class: className = 'inline-block' } = Astro.props;
---
<div class={className}>
<span class="align-super font-bold dark:text-slate-400">Share:</span>
<button class="ml-2" title="Twitter Share" data-aw-social-share="twitter" data-aw-url={url} data-aw-text={text}
><Icon name="logos:twitter" class="w-6 h-6" />
</button>
<button class="ml-2" title="Facebook Share" data-aw-social-share="facebook" data-aw-url={url}
><Icon name="logos:facebook" class="w-6 h-6" />
</button>
<button class="ml-2" title="Linkedin Share" data-aw-social-share="linkedin" data-aw-url={url} data-aw-text={text}
><Icon name="logos:linkedin-icon" class="w-6 h-6" />
</button>
<button class="ml-2" title="Whatsapp Share" data-aw-social-share="whatsapp" data-aw-url={url} data-aw-text={text}
><Icon name="logos:whatsapp" class="w-6 h-6" />
</button>
<button class="ml-2" title="Email Share" data-aw-social-share="mail" data-aw-url={url} data-aw-text={text}
><Icon name="tabler:mail" class="w-6 h-6" />
</button>
<span class="align-super font-bold dark:text-slate-400">Share:</span>
<button class="ml-2" title="Twitter Share" data-aw-social-share="twitter" data-aw-url={url} data-aw-text={text}
><Icon name="logos:twitter" class="w-6 h-6" />
</button>
<button class="ml-2" title="Facebook Share" data-aw-social-share="facebook" data-aw-url={url}
><Icon name="logos:facebook" class="w-6 h-6" />
</button>
<button class="ml-2" title="Linkedin Share" data-aw-social-share="linkedin" data-aw-url={url} data-aw-text={text}
><Icon name="logos:linkedin-icon" class="w-6 h-6" />
</button>
<button class="ml-2" title="Whatsapp Share" data-aw-social-share="whatsapp" data-aw-url={url} data-aw-text={text}
><Icon name="logos:whatsapp" class="w-6 h-6" />
</button>
<button class="ml-2" title="Email Share" data-aw-social-share="mail" data-aw-url={url} data-aw-text={text}
><Icon name="tabler:mail" class="w-6 h-6" />
</button>
</div>

View File

@ -5,21 +5,30 @@ import { BLOG } from '~/config.mjs';
import type { Post } from '~/types';
export interface Props {
tags: Post['tags'];
class?: string;
tags: Post['tags'];
class?: string;
}
const { tags, class: className = 'text-sm' } = Astro.props;
---
{
tags && Array.isArray(tags) && (
<ul class={className}>
{tags.map((tag) => (
<li class="bg-gray-100 dark:bg-slate-700 inline-block mr-2 mb-2 py-0.5 px-2 lowercase font-medium">
{BLOG?.tag?.disabled ? tag : <a href={getPermalink(tag, 'tag')} class="text-gray-600 dark:text-slate-300 hover:text-primary-800 dark:hover:text-gray-200">{tag}</a>}
</li>
))}
</ul>
)
tags && Array.isArray(tags) && (
<ul class={className}>
{tags.map((tag) => (
<li class="bg-gray-100 dark:bg-slate-700 inline-block mr-2 mb-2 py-0.5 px-2 lowercase font-medium">
{BLOG?.tag?.disabled ? (
tag
) : (
<a
href={getPermalink(tag, 'tag')}
class="text-gray-600 dark:text-slate-300 hover:text-primary-800 dark:hover:text-gray-200"
>
{tag}
</a>
)}
</li>
))}
</ul>
)
}

View File

@ -2,21 +2,21 @@
import { Icon } from 'astro-icon';
export interface Props {
label?: string;
class?: string;
iconClass?: string;
iconName?: string;
label?: string;
class?: string;
iconClass?: string;
iconName?: string;
}
const {
label = 'Toggle Menu',
class:
className = 'ml-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center transition',
iconClass = 'w-6 h-6',
iconName = 'tabler:menu',
label = 'Toggle Menu',
class:
className = 'ml-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center transition',
iconClass = 'w-6 h-6',
iconName = 'tabler:menu',
} = Astro.props;
---
<button type="button" class={className} aria-label={label} data-aw-toggle-menu>
<Icon name={iconName} class={iconClass} optimize={false} />
<Icon name={iconName} class={iconClass} optimize={false} />
</button>

View File

@ -2,21 +2,21 @@
import { Icon } from 'astro-icon';
export interface Props {
label?: string;
class?: string;
iconClass?: string;
iconName?: string;
label?: string;
class?: string;
iconClass?: string;
iconName?: string;
}
const {
label = 'Toggle between Dark and Light mode',
class:
className = 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center',
iconClass = 'w-6 h-6',
iconName = 'tabler:sun',
label = 'Toggle between Dark and Light mode',
class:
className = 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center',
iconClass = 'w-6 h-6',
iconName = 'tabler:sun',
} = Astro.props;
---
<button type="button" class={className} aria-label={label} data-aw-toggle-color-scheme>
<Icon name={iconName} class={iconClass} />
<Icon name={iconName} class={iconClass} />
</button>