refactor: major nitpicks

- refactor: change default import alias
- feat: add icons to breadcrumbs
- fix: add `site_name` og tag
- feat: hover on feedback for `Link`s and `TableofContentsHeadings`
- fix: add `external` to `SocialIcons`
This commit is contained in:
enscribe 2024-09-19 22:16:13 -07:00
parent 6764644c2e
commit 1ad80ac5bc
No known key found for this signature in database
GPG key ID: 9BBD5C4114E25322
26 changed files with 104 additions and 104 deletions

View file

@ -1,8 +1,8 @@
--- ---
import Link from '@/components/Link.astro'
import AvatarComponent from '@/components/ui/avatar' import AvatarComponent from '@/components/ui/avatar'
import type { Link as SocialLink } from '@/consts'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import Link from '@components/Link.astro'
import type { Link as SocialLink } from '@consts'
import type { CollectionEntry } from 'astro:content' import type { CollectionEntry } from 'astro:content'
import SocialIcons from './SocialIcons.astro' import SocialIcons from './SocialIcons.astro'

View file

@ -2,7 +2,7 @@
import AvatarComponent from '@/components/ui/avatar' import AvatarComponent from '@/components/ui/avatar'
import { Badge } from '@/components/ui/badge' import { Badge } from '@/components/ui/badge'
import { Separator } from '@/components/ui/separator' import { Separator } from '@/components/ui/separator'
import { formatDate, parseAuthors, readingTime } from '@lib/utils' import { formatDate, parseAuthors, readingTime } from '@/lib/utils'
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import type { CollectionEntry } from 'astro:content' import type { CollectionEntry } from 'astro:content'
import Link from './Link.astro' import Link from './Link.astro'
@ -29,12 +29,12 @@ const authors = await parseAuthors(entry.data.authors ?? [])
> >
{ {
entry.data.image && ( entry.data.image && (
<div class="sm:flex-shrink-0"> <div class="max-w-[200px] sm:flex-shrink-0">
<Image <Image
src={entry.data.image} src={entry.data.image}
alt={entry.data.title} alt={entry.data.title}
width={200} width={1200}
height={200} height={630}
class="object-cover" class="object-cover"
/> />
</div> </div>

View file

@ -36,13 +36,17 @@ const { items } = Astro.props
<BreadcrumbItem> <BreadcrumbItem>
{index === items.length - 1 ? ( {index === items.length - 1 ? (
<BreadcrumbPage> <BreadcrumbPage>
{item.icon && <Icon name={item.icon} class="mr-1 size-4" />} <span class="flex items-center gap-x-2">
{item.label} {item.icon && <Icon name={item.icon} class="size-4" />}
{item.label}
</span>
</BreadcrumbPage> </BreadcrumbPage>
) : ( ) : (
<BreadcrumbLink href={item.href}> <BreadcrumbLink href={item.href}>
{item.icon && <Icon name={item.icon} class="mr-1 size-4" />} <span class="flex items-center gap-x-2">
{item.label} {item.icon && <Icon name={item.icon} class="size-4" />}
{item.label}
</span>
</BreadcrumbLink> </BreadcrumbLink>
)} )}
</BreadcrumbItem> </BreadcrumbItem>

View file

@ -1,6 +1,6 @@
--- ---
import Container from '@components/Container.astro' import Container from '@/components/Container.astro'
import { SOCIAL_LINKS } from '@consts' import { SOCIAL_LINKS } from '@/consts'
import SocialIcons from './SocialIcons.astro' import SocialIcons from './SocialIcons.astro'
--- ---

View file

@ -2,6 +2,7 @@
import '../styles/global.css' import '../styles/global.css'
import '../styles/katex.css' import '../styles/katex.css'
import { SITE } from '@/consts'
import { ViewTransitions } from 'astro:transitions' import { ViewTransitions } from 'astro:transitions'
interface Props { interface Props {
@ -36,6 +37,7 @@ const { title, description, image = '/static/twitter-card.png' } = Astro.props
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} /> <meta property="og:url" content={Astro.url} />
<meta property="og:site_name" content={SITE.TITLE} />
<meta property="og:title" content={title} /> <meta property="og:title" content={title} />
<meta property="og:description" content={description} /> <meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} /> <meta property="og:image" content={new URL(image, Astro.url)} />

View file

@ -1,9 +1,9 @@
--- ---
import Container from '@/components/Container.astro'
import Link from '@/components/Link.astro'
import MobileMenu from '@/components/ui/mobile-menu'
import { ModeToggle } from '@/components/ui/mode-toggle' import { ModeToggle } from '@/components/ui/mode-toggle'
import Container from '@components/Container.astro' import { NAV_LINKS, SITE } from '@/consts'
import Link from '@components/Link.astro'
import MobileMenu from '@components/ui/mobile-menu'
import { NAV_LINKS, SITE } from '@consts'
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import logo from '../../public/static/logo.svg' import logo from '../../public/static/logo.svg'
--- ---

View file

@ -1,23 +1,15 @@
--- ---
import { cn } from '@lib/utils' import { cn } from '@/lib/utils'
type Props = { type Props = {
href: string href: string
external?: boolean external?: boolean
class?: string class?: string
underline?: boolean underline?: boolean
'data-heading'?: string
[key: string]: any [key: string]: any
} }
const { const { href, external, class: className, underline, ...rest } = Astro.props
href,
external,
class: className,
underline,
'data-heading': dataHeading,
...rest
} = Astro.props
--- ---
<a <a
@ -25,10 +17,10 @@ const {
target={external ? '_blank' : '_self'} target={external ? '_blank' : '_self'}
class={cn( class={cn(
'inline-block transition-colors duration-300 ease-in-out', 'inline-block transition-colors duration-300 ease-in-out',
underline && 'underline underline-offset-[3px]', underline &&
'underline decoration-muted-foreground underline-offset-[3px] hover:decoration-foreground',
className, className,
)} )}
data-heading={dataHeading}
{...rest} {...rest}
> >
<slot /> <slot />

View file

@ -1,7 +1,7 @@
--- ---
import Link from '@/components/Link.astro'
import { buttonVariants } from '@/components/ui/button' import { buttonVariants } from '@/components/ui/button'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import Link from '@components/Link.astro'
import { Icon } from 'astro-icon/components' import { Icon } from 'astro-icon/components'
const { prevPost, nextPost } = Astro.props const { prevPost, nextPost } = Astro.props

View file

@ -1,6 +1,6 @@
--- ---
import Link from '@/components/Link.astro'
import { Badge } from '@/components/ui/badge' import { Badge } from '@/components/ui/badge'
import Link from '@components/Link.astro'
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import type { CollectionEntry } from 'astro:content' import type { CollectionEntry } from 'astro:content'
@ -14,7 +14,7 @@ const { project } = Astro.props
<div <div
class="overflow-hidden rounded-xl border transition-colors duration-300 ease-in-out hover:bg-secondary/50" class="overflow-hidden rounded-xl border transition-colors duration-300 ease-in-out hover:bg-secondary/50"
> >
<Link href={project.data.link} class="block"> <Link href={project.data.link} class="block" external>
<Image <Image
src={project.data.image} src={project.data.image}
alt={project.data.name} alt={project.data.name}

View file

@ -1,8 +1,8 @@
--- ---
import Link from '@/components/Link.astro'
import { buttonVariants } from '@/components/ui/button' import { buttonVariants } from '@/components/ui/button'
import type { Link as SocialLink } from '@/consts'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import Link from '@components/Link.astro'
import type { Link as SocialLink } from '@consts'
import { Icon } from 'astro-icon/components' import { Icon } from 'astro-icon/components'
interface Props { interface Props {
@ -40,6 +40,7 @@ const getSocialLink = ({ href, label }: SocialLink) => ({
aria-label={ariaLabel} aria-label={ariaLabel}
title={ariaLabel} title={ariaLabel}
class={buttonVariants({ variant: 'outline', size: 'icon' })} class={buttonVariants({ variant: 'outline', size: 'icon' })}
external
> >
<Icon name={iconName} class="size-4" /> <Icon name={iconName} class="size-4" />
</Link> </Link>

View file

@ -10,7 +10,7 @@ const { heading } = Astro.props
> >
<Link <Link
href={'#' + heading.slug} href={'#' + heading.slug}
class="toc-link transition-colors duration-200 hover:underline" class="toc-link underline decoration-transparent underline-offset-[3px] transition-colors duration-200 hover:decoration-inherit"
> >
{heading.text} {heading.text}
</Link> </Link>

View file

@ -6,7 +6,7 @@ import {
DropdownMenuItem, DropdownMenuItem,
DropdownMenuTrigger, DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu' } from '@/components/ui/dropdown-menu'
import { NAV_LINKS } from '@consts' import { NAV_LINKS } from '@/consts'
import { Menu } from 'lucide-react' import { Menu } from 'lucide-react'
const MobileMenu = () => { const MobileMenu = () => {

View file

@ -70,18 +70,11 @@ This is a non-exhaustive list of features I believe are essential for a friction
This needs to be in every single template. This is an example of it being used in my `<Link>{:tsx}` component: This needs to be in every single template. This is an example of it being used in my `<Link>{:tsx}` component:
```astro showLineNumbers title="src/components/Link.astro" caption="A custom Link component with tailwind-merge and clsx" {17-21} ```astro showLineNumbers title="src/components/Link.astro" caption="A custom Link component with tailwind-merge and clsx" {16-20}
--- ---
import { cn } from '@lib/utils' import { cn } from '@/lib/utils'
const { const { href, external, class: className, underline, ...rest } = Astro.props
href,
external,
class: className,
underline,
'data-heading': dataHeading,
...rest
} = Astro.props
--- ---
<a <a
@ -89,10 +82,10 @@ This is a non-exhaustive list of features I believe are essential for a friction
target={external ? '_blank' : '_self'} target={external ? '_blank' : '_self'}
class={cn( class={cn(
'inline-block transition-colors duration-300 ease-in-out', 'inline-block transition-colors duration-300 ease-in-out',
underline && 'underline underline-offset-[3px]', underline &&
'underline decoration-muted-foreground underline-offset-[3px] hover:decoration-foreground',
className, className,
)} )}
data-heading={dataHeading}
{...rest} {...rest}
> >
<slot /> <slot />

View file

@ -1,8 +1,8 @@
--- ---
import Footer from '@components/Footer.astro' import Footer from '@/components/Footer.astro'
import Head from '@components/Head.astro' import Head from '@/components/Head.astro'
import Header from '@components/Header.astro' import Header from '@/components/Header.astro'
import { SITE } from '@consts' import { SITE } from '@/consts'
type Props = { type Props = {
title: string title: string

View file

@ -1,16 +1,16 @@
--- ---
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import Container from '@/components/Container.astro'
import Link from '@/components/Link.astro'
import { buttonVariants } from '@/components/ui/button' import { buttonVariants } from '@/components/ui/button'
import Container from '@components/Container.astro' import { SITE } from '@/consts'
import Link from '@components/Link.astro' import Layout from '@/layouts/Layout.astro'
import { SITE } from '@consts' import { cn } from '@/lib/utils'
import Layout from '@layouts/Layout.astro'
import { cn } from '@lib/utils'
--- ---
<Layout title="404" description={SITE.DESCRIPTION}> <Layout title="404" description={SITE.DESCRIPTION}>
<Container class="flex grow flex-col gap-y-6"> <Container class="flex grow flex-col gap-y-6">
<Breadcrumbs items={[{ label: '???' }]} /> <Breadcrumbs items={[{ label: '???', icon: 'lucide:circle-help' }]} />
<section <section
class="flex flex-col items-center justify-center gap-y-4 text-center" class="flex flex-col items-center justify-center gap-y-4 text-center"

View file

@ -1,9 +1,9 @@
--- ---
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import Container from '@components/Container.astro' import Container from '@/components/Container.astro'
import ProjectCard from '@components/ProjectCard.astro' import ProjectCard from '@/components/ProjectCard.astro'
import { SITE } from '@consts' import { SITE } from '@/consts'
import Layout from '@layouts/Layout.astro' import Layout from '@/layouts/Layout.astro'
import { getCollection } from 'astro:content' import { getCollection } from 'astro:content'
const projects = await getCollection('projects') const projects = await getCollection('projects')
@ -11,7 +11,7 @@ const projects = await getCollection('projects')
<Layout title="About" description={SITE.DESCRIPTION}> <Layout title="About" description={SITE.DESCRIPTION}>
<Container class="flex flex-col gap-y-6"> <Container class="flex flex-col gap-y-6">
<Breadcrumbs items={[{ label: 'About' }]} /> <Breadcrumbs items={[{ label: 'About', icon: 'lucide:info' }]} />
<section> <section>
<div class="min-w-full"> <div class="min-w-full">

View file

@ -1,9 +1,9 @@
--- ---
import AuthorCard from '@/components/AuthorCard.astro'
import BlogCard from '@/components/BlogCard.astro'
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import AuthorCard from '@components/AuthorCard.astro' import Container from '@/components/Container.astro'
import BlogCard from '@components/BlogCard.astro' import Layout from '@/layouts/Layout.astro'
import Container from '@components/Container.astro'
import Layout from '@layouts/Layout.astro'
import { type CollectionEntry, getCollection } from 'astro:content' import { type CollectionEntry, getCollection } from 'astro:content'
export async function getStaticPaths() { export async function getStaticPaths() {
@ -35,8 +35,8 @@ const authorPosts = allPosts
<Container class="flex flex-col gap-y-6"> <Container class="flex flex-col gap-y-6">
<Breadcrumbs <Breadcrumbs
items={[ items={[
{ href: '/authors', label: 'Authors' }, { href: '/authors', label: 'Authors', icon: 'lucide:users' },
{ label: author.data.name }, { label: author.data.name, icon: 'lucide:user' },
]} ]}
/> />

View file

@ -1,8 +1,8 @@
--- ---
import AuthorCard from '@/components/AuthorCard.astro'
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import AuthorCard from '@components/AuthorCard.astro' import Container from '@/components/Container.astro'
import Container from '@components/Container.astro' import Layout from '@/layouts/Layout.astro'
import Layout from '@layouts/Layout.astro'
import { getCollection } from 'astro:content' import { getCollection } from 'astro:content'
const authors = await getCollection('authors') const authors = await getCollection('authors')
@ -10,7 +10,7 @@ const authors = await getCollection('authors')
<Layout title="Authors" description="A list of authors on this site."> <Layout title="Authors" description="A list of authors on this site.">
<Container class="flex flex-col gap-y-6"> <Container class="flex flex-col gap-y-6">
<Breadcrumbs items={[{ label: 'Authors' }]} /> <Breadcrumbs items={[{ label: 'Authors', icon: 'lucide:users' }]} />
{ {
authors.length > 0 ? ( authors.length > 0 ? (
<ul class="not-prose flex flex-col gap-4"> <ul class="not-prose flex flex-col gap-4">

View file

@ -1,10 +1,10 @@
--- ---
import BlogCard from '@/components/BlogCard.astro'
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import Container from '@/components/Container.astro'
import PaginationComponent from '@/components/ui/pagination' import PaginationComponent from '@/components/ui/pagination'
import { SITE } from '@/consts' import { SITE } from '@/consts'
import BlogCard from '@components/BlogCard.astro' import Layout from '@/layouts/Layout.astro'
import Container from '@components/Container.astro'
import Layout from '@layouts/Layout.astro'
import type { PaginateFunction } from 'astro' import type { PaginateFunction } from 'astro'
import { type CollectionEntry, getCollection } from 'astro:content' import { type CollectionEntry, getCollection } from 'astro:content'
@ -38,8 +38,8 @@ const years = Object.keys(postsByYear).sort((a, b) => parseInt(b) - parseInt(a))
<Container class="flex grow flex-col gap-y-6"> <Container class="flex grow flex-col gap-y-6">
<Breadcrumbs <Breadcrumbs
items={[ items={[
{ label: 'Blog', href: '/blog' }, { label: 'Blog', href: '/blog', icon: 'lucide:archive' },
{ label: `Page ${page.currentPage}` }, { label: `Page ${page.currentPage}`, icon: 'lucide:folder-open' },
]} ]}
/> />

View file

@ -1,14 +1,14 @@
--- ---
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import Container from '@/components/Container.astro'
import Link from '@/components/Link.astro'
import PostNavigation from '@/components/PostNavigation.astro'
import TableOfContents from '@/components/TableOfContents.astro'
import { badgeVariants } from '@/components/ui/badge' import { badgeVariants } from '@/components/ui/badge'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator' import { Separator } from '@/components/ui/separator'
import Container from '@components/Container.astro' import Layout from '@/layouts/Layout.astro'
import Link from '@components/Link.astro' import { formatDate, parseAuthors, readingTime } from '@/lib/utils'
import PostNavigation from '@components/PostNavigation.astro'
import TableOfContents from '@components/TableOfContents.astro'
import Layout from '@layouts/Layout.astro'
import { formatDate, parseAuthors, readingTime } from '@lib/utils'
import { Icon } from 'astro-icon/components' import { Icon } from 'astro-icon/components'
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import { type CollectionEntry, getCollection } from 'astro:content' import { type CollectionEntry, getCollection } from 'astro:content'
@ -61,7 +61,10 @@ const authors = await parseAuthors(post.data.authors ?? [])
> >
<Container class="flex flex-col gap-y-6"> <Container class="flex flex-col gap-y-6">
<Breadcrumbs <Breadcrumbs
items={[{ href: '/blog', label: 'Blog' }, { label: post.data.title }]} items={[
{ href: '/blog', label: 'Blog', icon: 'lucide:archive' },
{ label: post.data.title, icon: 'lucide:file-text' },
]}
/> />
{ {

View file

@ -1,4 +1,7 @@
--- ---
import BlogCard from '@/components/BlogCard.astro'
import Container from '@/components/Container.astro'
import Link from '@/components/Link.astro'
import { buttonVariants } from '@/components/ui/button' import { buttonVariants } from '@/components/ui/button'
import { import {
Card, Card,
@ -7,11 +10,8 @@ import {
CardHeader, CardHeader,
CardTitle, CardTitle,
} from '@/components/ui/card' } from '@/components/ui/card'
import BlogCard from '@components/BlogCard.astro' import { SITE } from '@/consts'
import Container from '@components/Container.astro' import Layout from '@/layouts/Layout.astro'
import Link from '@components/Link.astro'
import { SITE } from '@consts'
import Layout from '@layouts/Layout.astro'
import { getCollection } from 'astro:content' import { getCollection } from 'astro:content'
const blog = (await getCollection('blog')) const blog = (await getCollection('blog'))

View file

@ -1,5 +1,5 @@
import rss from '@astrojs/rss' import rss from '@astrojs/rss'
import { SITE } from '@consts' import { SITE } from '@/consts'
import type { APIContext } from 'astro' import type { APIContext } from 'astro'
import { getCollection } from 'astro:content' import { getCollection } from 'astro:content'

View file

@ -1,8 +1,8 @@
--- ---
import BlogCard from '@components/BlogCard.astro' import BlogCard from '@/components/BlogCard.astro'
import Breadcrumbs from '@components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import Container from '@components/Container.astro' import Container from '@/components/Container.astro'
import Layout from '@layouts/Layout.astro' import Layout from '@/layouts/Layout.astro'
import { Icon } from 'astro-icon/components' import { Icon } from 'astro-icon/components'
import { type CollectionEntry, getCollection } from 'astro:content' import { type CollectionEntry, getCollection } from 'astro:content'
@ -37,7 +37,12 @@ export async function getStaticPaths() {
description={`A collection of posts tagged with ${tag}.`} description={`A collection of posts tagged with ${tag}.`}
> >
<Container class="flex flex-col gap-y-6"> <Container class="flex flex-col gap-y-6">
<Breadcrumbs items={[{ href: '/tags', label: 'Tags' }, { label: tag }]} /> <Breadcrumbs
items={[
{ href: '/tags', label: 'Tags', icon: 'lucide:tags' },
{ label: tag, icon: 'lucide:tag' },
]}
/>
<div class="flex flex-wrap items-center gap-2"> <div class="flex flex-wrap items-center gap-2">
<h1 class="text-3xl font-semibold">Posts tagged with</h1> <h1 class="text-3xl font-semibold">Posts tagged with</h1>
<span <span

View file

@ -1,9 +1,9 @@
--- ---
import Breadcrumbs from '@/components/Breadcrumbs.astro' import Breadcrumbs from '@/components/Breadcrumbs.astro'
import Container from '@components/Container.astro' import Container from '@/components/Container.astro'
import Link from '@components/Link.astro' import Link from '@/components/Link.astro'
import { badgeVariants } from '@components/ui/badge' import { badgeVariants } from '@/components/ui/badge'
import Layout from '@layouts/Layout.astro' import Layout from '@/layouts/Layout.astro'
import { Icon } from 'astro-icon/components' import { Icon } from 'astro-icon/components'
import { getCollection } from 'astro:content' import { getCollection } from 'astro:content'
@ -16,7 +16,7 @@ const tags = blog
<Layout title="Tags" description="A list of all tags used in blog posts"> <Layout title="Tags" description="A list of all tags used in blog posts">
<Container class="flex flex-col gap-y-6"> <Container class="flex flex-col gap-y-6">
<Breadcrumbs items={[{ label: 'Tags' }]} /> <Breadcrumbs items={[{ label: 'Tags', icon: 'lucide:tags' }]} />
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<h1 class="text-3xl font-semibold">Tags</h1> <h1 class="text-3xl font-semibold">Tags</h1>

View file

@ -77,13 +77,13 @@
.disable-transitions, .disable-transitions,
.disable-transitions * { .disable-transitions * {
transition: none !important; @apply !transition-none;
} }
} }
@layer components { @layer components {
article { article {
@apply prose-headings:scroll-mt-20 prose-headings:break-words prose-p:break-words prose-pre:!px-0; @apply prose-headings:scroll-mt-20 prose-headings:break-words prose-p:break-words prose-a:!decoration-muted-foreground prose-a:underline-offset-[3px] prose-a:transition-colors hover:prose-a:!decoration-foreground prose-pre:!px-0 prose-img:mx-auto;
.katex-display { .katex-display {
@apply overflow-x-auto overflow-y-hidden py-4; @apply overflow-x-auto overflow-y-hidden py-4;
@ -169,7 +169,7 @@
/* Copy button */ /* Copy button */
> button:has(> span) { > button:has(> span) {
@apply right-0.5 top-[3px] m-0 size-8 rounded-md bg-transparent p-1 backdrop-blur-none; @apply right-0.5 top-[3px] m-0 size-8 rounded-md bg-background p-1 backdrop-blur-none transition-all;
} }
} }
} }

View file

@ -4,7 +4,7 @@
"strictNullChecks": true, "strictNullChecks": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@*": ["./src/*"] "@/*": ["./src/*"]
}, },
"jsx": "react-jsx", "jsx": "react-jsx",
"jsxImportSource": "react" "jsxImportSource": "react"