Skip to content

Commit

Permalink
feature/alpinejs
Browse files Browse the repository at this point in the history
  • Loading branch information
penrodlol authored Apr 22, 2024
1 parent 98321f9 commit c67aa71
Show file tree
Hide file tree
Showing 25 changed files with 243 additions and 287 deletions.
34 changes: 34 additions & 0 deletions alpine.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Alpine } from 'alpinejs';

type PagefindResult = Record<string, unknown>;
type PagefindResults = { results: Array<{ data: () => Promise<{ meta: PagefindResult }> }> };

export default (Alpine: Alpine) => {
Alpine.magic('fetch', () => async (...props: Parameters<typeof fetch>) => {
if (props[1]?.body) props[1].body = JSON.stringify(props[1].body);
return await fetch(...props).then((res) => res.json());
});

Alpine.data('pagefind', (data: Array<PagefindResult>, key: string) => ({
query: null as string | null,
tags: [],
results: data,
async init() {
this.$watch('query', () => this.execute());
this.$watch('tags', () => this.execute());

if (window.Pagefind) return;
window.Pagefind = await import(String(/* @vite-ignore */ import.meta.env.PUBLIC_PAGEFIND_URL));
await window.Pagefind.init();
},
async execute() {
if (!this.query?.trim()?.length && !this.tags?.length) this.results = data;
else {
const filters = { filters: { tag: { any: this.tags } } };
const { results }: PagefindResults = await window.Pagefind.search(this.query, filters);
const payload = await Promise.all(results.map(async (result) => result.data()));
this.results = payload.map((item) => data.find((result) => result[key] === item.meta[key])) as typeof data;
}
},
}));
};
4 changes: 3 additions & 1 deletion astro.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import alpine from '@astrojs/alpinejs';
import db from '@astrojs/db';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
Expand All @@ -22,7 +23,7 @@ export default defineConfig({
() => (tree, vfile) => {
const data = vfile.data as { astro: { frontmatter: Record<string, unknown> } };
const payload = Math.round(readingTime(toString(tree)).minutes);
data.astro.frontmatter.readingTime = payload;
data.astro.frontmatter.readingTime = `${payload} Min Read`;

visit(tree, 'element', (node) => {
if (node.properties?.['data-rehype-pretty-code-title'] !== '') return;
Expand All @@ -36,6 +37,7 @@ export default defineConfig({
tailwind(),
mdx(),
db(),
alpine({ entrypoint: '/alpine.config.ts' }),
sitemap({ changefreq: 'daily', lastmod: new Date() }),
robotsTxt({ host: true, policy: [{ userAgent: '*', disallow: ['/404'] }] }),
],
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,26 @@
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build && pagefind --site .vercel/output/static",
"build": "astro build --remote && pagefind --site .vercel/output/static",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/db": "^0.10.2",
"alpinejs": "^3.13.8",
"astro": "^4.5.17",
"pagefind": "^1.1.0"
},
"devDependencies": {
"@astrojs/alpinejs": "^0.4.0",
"@astrojs/mdx": "^2.2.4",
"@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.1.2",
"@astrojs/tailwind": "^5.1.0",
"@astrojs/vercel": "^7.5.2",
"@fontsource/inter": "^5.0.17",
"@octokit/rest": "^20.1.0",
"@types/alpinejs": "^3.13.10",
"astro-og-canvas": "^0.4.2",
"astro-robots-txt": "^1.0.0",
"lucide-astro": "^0.366.0",
Expand All @@ -35,6 +38,7 @@
"sass": "^1.74.1",
"shiki": "^1.3.0",
"tailwind-merge": "^2.2.2",
"tailwind-variants": "^0.2.1",
"tailwindcss": "^3.4.3",
"tailwindcss-fluid-type": "^2.0.6",
"unist-util-visit": "^5.0.0"
Expand Down
7 changes: 2 additions & 5 deletions prettier.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ module.exports = {
semi: true,
trailingComma: 'all',
proseWrap: 'always',
printWidth: 100,
printWidth: 120,
tailwindFunctions: ['twMerge', 'twJoin'],
overrides: [{ files: '*.astro', options: { parser: 'astro' } }],
plugins: [
require.resolve('prettier-plugin-astro'),
require.resolve('prettier-plugin-tailwindcss'),
],
plugins: [require.resolve('prettier-plugin-astro'), require.resolve('prettier-plugin-tailwindcss')],
};
5 changes: 2 additions & 3 deletions src/components/post-card.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Image } from 'astro:assets';
import type { CollectionEntry } from 'astro:content';
import { Calendar, Clock4 } from 'lucide-astro';
import { twJoin } from 'tailwind-merge';
import Moment from './ui/moment.astro';
import Separator from './ui/separator.astro';
type Props = { post: CollectionEntry<'posts'> };
Expand Down Expand Up @@ -32,11 +31,11 @@ const { remarkPluginFrontmatter } = await post.render();
<div class="flex justify-between gap-4 text-xxs text-2">
<div class="flex items-center gap-2">
<Calendar class="shrink-0" size={14} aria-hidden />
<Moment>{post.data.published}</Moment>
<time datetime={post.data.published.iso}>{post.data.published.pretty}</time>
</div>
<div class="flex items-center gap-2">
<Clock4 class="shrink-0" size={14} aria-hidden />
<span>{remarkPluginFrontmatter.readingTime} Min Read</span>
<span>{remarkPluginFrontmatter.readingTime}</span>
</div>
</div>
</div>
Expand Down
5 changes: 2 additions & 3 deletions src/components/post-code.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import { twJoin } from 'tailwind-merge';
import Clipboard from './ui/clipboard.astro';
---

<figure {...Astro.props} data-clipboard-wrapper class="rounded border">
<figure {...Astro.props} class="rounded border">
<figcaption class="flex items-center rounded-t border-b bg-2 pl-4 text-xxs text-2">
<slot name="title" />
<Clipboard class="ml-auto px-4 py-1.5" />
<Clipboard target="$el.parentElement.nextElementSibling" class="ml-auto px-4 py-1.5" />
</figcaption>
<div
data-clipboard-content
class={twJoin(
// base
'overflow-auto bg-[--shiki-color-background] p-4 font-sans text-xxs',
Expand Down
60 changes: 0 additions & 60 deletions src/components/post-line.astro

This file was deleted.

58 changes: 58 additions & 0 deletions src/components/post-results.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
import type { PostResults } from '@/pages/blog/index.astro';
import { Dot } from 'lucide-astro';
import { tv } from 'tailwind-variants';
import Separator from './ui/separator.astro';
type Props = { results: PostResults };
const title = tv({ base: 'group-hover:text-emphasis motion-safe:transition-colors' });
const stats = tv({ base: 'flex items-center !text-xxs text-2' });
const dot = tv({ base: 'shrink-4 size-4' });
const horizontalSeparator = tv({ base: 'flex-1' });
const verticalSeparator = tv({ base: 'mt-4 sm:hidden' });
const anchor = tv({
base: [
'group flex flex-col rounded py-2 text-xs',
'sm:flex-row sm:items-center sm:justify-between sm:gap-2',
'focus-visible:outline-none focus-visible:ring-1',
],
});
---

<ul x-cloak class="peer [&[x-cloak]]:hidden">
<template x-for="post in results">
<li>
<a :href="'/blog/' + post.slug" :aria-label="post.title" class={anchor()}>
<span x-text="post.title" class={title()}></span>
<Separator class={horizontalSeparator()} />
<div class={stats()}>
<time :datetime="post.published.iso" x-text="post.published.pretty"></time>
<Dot class={dot()} aria-hidden />
<span x-text="post.readingTime"></span>
</div>
<Separator class={verticalSeparator()} />
</a>
</li>
</template>
</ul>

<!-- Fallback if JavaScript is disabled -->
<ul class="peer-[:not([x-cloak])]:hidden">
{
Astro.props.results.map((post) => (
<li>
<a href={`/blog/${post.slug}`} aria-label={post.title} class={anchor()}>
<span class={title()}>{post.title}</span>
<Separator class={horizontalSeparator()} />
<div class={stats()}>
<time datetime="post.published.iso">{post.published.pretty}</time>
<Dot class={dot()} aria-hidden />
<span>{post.readingTime}</span>
</div>
<Separator class={verticalSeparator()} />
</a>
</li>
))
}
</ul>
20 changes: 0 additions & 20 deletions src/components/post-views.astro

This file was deleted.

9 changes: 1 addition & 8 deletions src/components/socials.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Clipboard from './ui/clipboard.astro';
import Link from './ui/link.astro';
---

<details data-socials class="group relative">
<details x-data class="group relative" @click.outside="$el.open && ($el.open = false)">
<summary
class={twJoin(
'group peer flex cursor-pointer select-none list-none items-center gap-1 rounded',
Expand Down Expand Up @@ -38,10 +38,3 @@ import Link from './ui/link.astro';
</ul>
</div>
</details>

<script>
document.addEventListener('astro:page-load', () => {
const el = document.querySelector('[data-socials]') as HTMLDetailsElement;
document.addEventListener('click', (e) => !el.contains(e.target as Node) && (el.open = false));
});
</script>
21 changes: 7 additions & 14 deletions src/components/ui/chip.astro
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
---
import type { HTMLAttributes } from 'astro/types';
import { twJoin, twMerge } from 'tailwind-merge';
import { twMerge } from 'tailwind-merge';
type Props = Omit<HTMLAttributes<'input'>, 'type'>;
type Props = Omit<HTMLAttributes<'input'>, 'type'> & { value: string };
const { class: className, ...props } = Astro.props;
const { class: className, value, ...props } = Astro.props;
---

<label class={twMerge('relative flex rounded border bg-3 px-2 text-2', className)}>
<input
{...props}
{value}
type="checkbox"
class={twJoin(
'peer absolute inset-0 cursor-pointer appearance-none rounded',
'checked:ring-1 focus-visible:outline-none focus-visible:ring-1',
)}
class="peer absolute inset-0 cursor-pointer appearance-none rounded checked:ring-1 focus-visible:outline-none focus-visible:ring-1"
/>
<div
class={twJoin(
'text-xxs peer-checked:text-emphasis peer-hover:text-emphasis',
'motion-safe:transition-colors',
)}
>
<slot />
<div class="text-xxs peer-checked:text-emphasis peer-hover:text-emphasis motion-safe:transition-colors">
{value}
</div>
</label>
33 changes: 7 additions & 26 deletions src/components/ui/clipboard.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,24 @@ import type { HTMLAttributes } from 'astro/types';
import { Check, Clipboard as ClipboardIcon } from 'lucide-astro';
import { twMerge } from 'tailwind-merge';
type Props = HTMLAttributes<'button'> & { content?: string };
type Props = HTMLAttributes<'button'> & { content?: string; target?: string };
const { class: className, 'aria-label': ariaLabel, content, ...props } = Astro.props;
const { class: className, 'aria-label': ariaLabel, content, target, ...props } = Astro.props;
---

<button
{...props}
data-copied="false"
data-content={content}
x-data="{ copied: false }"
aria-label={ariaLabel ?? 'Copy to clipboard'}
@click={`navigator.clipboard.writeText(${target} ? ${target}?.textContent?.trim() : "${content}").then(() => copied = true)`}
@mouseleave.debounce.1000ms="copied && (copied = false)"
class={twMerge(
'group flex select-none items-center gap-2 rounded hover:text-emphasis',
'focus-visible:outline-none focus-visible:ring-2 motion-safe:transition-colors',
className,
)}
>
<slot />
<ClipboardIcon size={14} aria-hidden class="group-data-[copied=true]:hidden" />
<Check size={14} aria-hidden class="group-data-[copied=false]:hidden" />
<ClipboardIcon size={14} aria-hidden x-show="!copied" />
<Check size={14} aria-hidden x-show="copied" />
</button>

<script>
document.addEventListener('astro:page-load', () => {
const targets: NodeListOf<HTMLButtonElement> = document.querySelectorAll('button[data-copied]');

targets.forEach((target) => {
target.addEventListener('click', () => {
target.dataset.copied = 'true';
setTimeout(() => (target.dataset.copied = 'false'), 1000);

if (target.dataset.content) navigator.clipboard.writeText(target.dataset.content);
else {
const wrapper = target.closest('[data-clipboard-wrapper]');
const content = wrapper?.querySelector('[data-clipboard-content]')?.textContent?.trim();
if (content) navigator.clipboard.writeText(content);
}
});
});
});
</script>
Loading

0 comments on commit c67aa71

Please sign in to comment.