refactor: update component props and improve types (#600)

- stop exporting component Props
- replace interface with type for component Props
- enhance dynamic rendering in several components
This commit is contained in:
Sat Naing
2026-01-05 22:56:38 +07:00
committed by GitHub
parent f5f863f9d2
commit 7141d82dbd
9 changed files with 40 additions and 53 deletions
+14 -19
View File
@@ -1,36 +1,31 @@
---
import { slugifyStr } from "@/utils/slugify";
import type { CollectionEntry } from "astro:content";
import { slugifyStr } from "@/utils/slugify";
import { getPath } from "@/utils/getPath";
import Datetime from "./Datetime.astro";
export interface Props extends CollectionEntry<"blog"> {
type Props = {
variant?: "h2" | "h3";
}
} & CollectionEntry<"blog">;
const { variant = "h2", data, id, filePath } = Astro.props;
const { variant: Heading = "h2", id, data, filePath } = Astro.props;
const { title, description, pubDatetime, modDatetime, timezone } = data;
const headerProps = {
style: { viewTransitionName: slugifyStr(title) },
class: "text-lg font-medium decoration-dashed hover:underline",
};
const { title, description, ...props } = data;
---
<li class="my-6">
<a
href={getPath(id, filePath)}
class="inline-block text-lg font-medium text-accent decoration-dashed underline-offset-4 focus-visible:no-underline focus-visible:underline-offset-0"
class:list={[
"inline-block text-lg font-medium text-accent",
"decoration-dashed underline-offset-4 hover:underline",
"focus-visible:no-underline focus-visible:underline-offset-0",
]}
>
{
variant === "h2" ? (
<h2 {...headerProps}>{title}</h2>
) : (
<h3 {...headerProps}>{title}</h3>
)
}
<Heading style={{ viewTransitionName: slugifyStr(title) }}>
{title}
</Heading>
</a>
<Datetime {pubDatetime} {modDatetime} {timezone} />
<Datetime {...props} />
<p>{description}</p>
</li>
+5 -5
View File
@@ -8,13 +8,13 @@ import { SITE } from "@/config";
dayjs.extend(utc);
dayjs.extend(timezone);
export interface Props {
type Props = {
class?: string;
size?: "sm" | "lg";
timezone: string | undefined;
pubDatetime: string | Date;
modDatetime: string | Date | undefined | null;
}
timezone?: string;
modDatetime?: string | Date | null;
};
const {
pubDatetime,
@@ -37,7 +37,7 @@ const date = datetime.format("D MMM, YYYY"); // e.g., '22 Mar, 2025'
<div class:list={["flex items-center gap-x-2 opacity-80", className]}>
<IconCalendar
class:list={[
"inline-block size-6 min-w-[1.375rem]",
"inline-block size-6 min-w-5.5",
{ "scale-90": size === "sm" },
]}
/>
+2 -2
View File
@@ -3,11 +3,11 @@ import type { CollectionEntry } from "astro:content";
import IconEdit from "@/assets/icons/IconEdit.svg";
import { SITE } from "@/config";
export interface Props {
type Props = {
hideEditPost?: CollectionEntry<"blog">["data"]["hideEditPost"];
class?: string;
post: CollectionEntry<"blog">;
}
};
const { hideEditPost, post, class: className = "" } = Astro.props;
+8 -4
View File
@@ -1,16 +1,20 @@
---
import type { HTMLAttributes } from "astro/types";
import Socials from "./Socials.astro";
const currentYear = new Date().getFullYear();
export interface Props {
type Props = {
noMarginTop?: boolean;
}
} & HTMLAttributes<"footer">;
const { noMarginTop = false } = Astro.props;
const { noMarginTop = false, class: className, ...attrs } = Astro.props;
---
<footer class:list={["app-layout", { "mt-auto": !noMarginTop }]}>
<footer
class:list={["app-layout", { "mt-auto": !noMarginTop }, className]}
{...attrs}
>
<div
class:list={[
"py-6 sm:py-4",
+2 -2
View File
@@ -5,9 +5,9 @@ import IconArrowLeft from "@/assets/icons/IconArrowLeft.svg";
import IconArrowRight from "@/assets/icons/IconArrowRight.svg";
import LinkButton from "./LinkButton.astro";
export interface Props {
type Props = {
page: Page<CollectionEntry<"blog">>;
}
};
const { page } = Astro.props;
---
+2 -6
View File
@@ -1,16 +1,12 @@
---
import type { MarkdownLayoutProps } from "astro";
import Header from "@/components/Header.astro";
import Footer from "@/components/Footer.astro";
import Breadcrumb from "@/components/Breadcrumb.astro";
import Layout from "./Layout.astro";
import { SITE } from "@/config";
export interface Props {
frontmatter: {
title: string;
description?: string;
};
}
type Props = MarkdownLayoutProps<{ title: string }>;
const { frontmatter } = Astro.props;
---
+2 -2
View File
@@ -4,7 +4,7 @@ import { PUBLIC_GOOGLE_SITE_VERIFICATION } from "astro:env/client";
import { SITE } from "@/config";
import "@/styles/global.css";
export interface Props {
type Props = {
title?: string;
author?: string;
profile?: string;
@@ -14,7 +14,7 @@ export interface Props {
pubDatetime?: Date;
modDatetime?: Date | null;
scrollSmooth?: boolean;
}
};
const {
title = SITE.title,
+3 -11
View File
@@ -2,18 +2,10 @@
import Breadcrumb from "@/components/Breadcrumb.astro";
import { SITE } from "@/config";
interface StringTitleProp {
pageTitle: string;
pageDesc?: string;
}
type StringTitle = { pageTitle: string };
type ArrayTitle = { pageTitle: [string, string]; titleTransition: string };
interface ArrayTitleProp {
pageTitle: [string, string];
titleTransition: string;
pageDesc?: string;
}
export type Props = StringTitleProp | ArrayTitleProp;
type Props = (StringTitle | ArrayTitle) & { pageDesc?: string };
const { props } = Astro;
+2 -2
View File
@@ -4,9 +4,9 @@ import PostDetails from "@/layouts/PostDetails.astro";
import getSortedPosts from "@/utils/getSortedPosts";
import { getPath } from "@/utils/getPath";
export interface Props {
type Props = {
post: CollectionEntry<"blog">;
}
};
export async function getStaticPaths() {
const posts = await getCollection("blog", ({ data }) => !data.draft);