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 type { CollectionEntry } from "astro:content";
import { slugifyStr } from "@/utils/slugify";
import { getPath } from "@/utils/getPath"; import { getPath } from "@/utils/getPath";
import Datetime from "./Datetime.astro"; import Datetime from "./Datetime.astro";
export interface Props extends CollectionEntry<"blog"> { type Props = {
variant?: "h2" | "h3"; 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 { title, description, ...props } = data;
const headerProps = {
style: { viewTransitionName: slugifyStr(title) },
class: "text-lg font-medium decoration-dashed hover:underline",
};
--- ---
<li class="my-6"> <li class="my-6">
<a <a
href={getPath(id, filePath)} 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",
]}
> >
{ <Heading style={{ viewTransitionName: slugifyStr(title) }}>
variant === "h2" ? ( {title}
<h2 {...headerProps}>{title}</h2> </Heading>
) : (
<h3 {...headerProps}>{title}</h3>
)
}
</a> </a>
<Datetime {pubDatetime} {modDatetime} {timezone} /> <Datetime {...props} />
<p>{description}</p> <p>{description}</p>
</li> </li>
+5 -5
View File
@@ -8,13 +8,13 @@ import { SITE } from "@/config";
dayjs.extend(utc); dayjs.extend(utc);
dayjs.extend(timezone); dayjs.extend(timezone);
export interface Props { type Props = {
class?: string; class?: string;
size?: "sm" | "lg"; size?: "sm" | "lg";
timezone: string | undefined;
pubDatetime: string | Date; pubDatetime: string | Date;
modDatetime: string | Date | undefined | null; timezone?: string;
} modDatetime?: string | Date | null;
};
const { const {
pubDatetime, 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]}> <div class:list={["flex items-center gap-x-2 opacity-80", className]}>
<IconCalendar <IconCalendar
class:list={[ class:list={[
"inline-block size-6 min-w-[1.375rem]", "inline-block size-6 min-w-5.5",
{ "scale-90": size === "sm" }, { "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 IconEdit from "@/assets/icons/IconEdit.svg";
import { SITE } from "@/config"; import { SITE } from "@/config";
export interface Props { type Props = {
hideEditPost?: CollectionEntry<"blog">["data"]["hideEditPost"]; hideEditPost?: CollectionEntry<"blog">["data"]["hideEditPost"];
class?: string; class?: string;
post: CollectionEntry<"blog">; post: CollectionEntry<"blog">;
} };
const { hideEditPost, post, class: className = "" } = Astro.props; 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"; import Socials from "./Socials.astro";
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
export interface Props { type Props = {
noMarginTop?: boolean; 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 <div
class:list={[ class:list={[
"py-6 sm:py-4", "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 IconArrowRight from "@/assets/icons/IconArrowRight.svg";
import LinkButton from "./LinkButton.astro"; import LinkButton from "./LinkButton.astro";
export interface Props { type Props = {
page: Page<CollectionEntry<"blog">>; page: Page<CollectionEntry<"blog">>;
} };
const { page } = Astro.props; const { page } = Astro.props;
--- ---
+2 -6
View File
@@ -1,16 +1,12 @@
--- ---
import type { MarkdownLayoutProps } from "astro";
import Header from "@/components/Header.astro"; import Header from "@/components/Header.astro";
import Footer from "@/components/Footer.astro"; import Footer from "@/components/Footer.astro";
import Breadcrumb from "@/components/Breadcrumb.astro"; import Breadcrumb from "@/components/Breadcrumb.astro";
import Layout from "./Layout.astro"; import Layout from "./Layout.astro";
import { SITE } from "@/config"; import { SITE } from "@/config";
export interface Props { type Props = MarkdownLayoutProps<{ title: string }>;
frontmatter: {
title: string;
description?: string;
};
}
const { frontmatter } = Astro.props; 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 { SITE } from "@/config";
import "@/styles/global.css"; import "@/styles/global.css";
export interface Props { type Props = {
title?: string; title?: string;
author?: string; author?: string;
profile?: string; profile?: string;
@@ -14,7 +14,7 @@ export interface Props {
pubDatetime?: Date; pubDatetime?: Date;
modDatetime?: Date | null; modDatetime?: Date | null;
scrollSmooth?: boolean; scrollSmooth?: boolean;
} };
const { const {
title = SITE.title, title = SITE.title,
+3 -11
View File
@@ -2,18 +2,10 @@
import Breadcrumb from "@/components/Breadcrumb.astro"; import Breadcrumb from "@/components/Breadcrumb.astro";
import { SITE } from "@/config"; import { SITE } from "@/config";
interface StringTitleProp { type StringTitle = { pageTitle: string };
pageTitle: string; type ArrayTitle = { pageTitle: [string, string]; titleTransition: string };
pageDesc?: string;
}
interface ArrayTitleProp { type Props = (StringTitle | ArrayTitle) & { pageDesc?: string };
pageTitle: [string, string];
titleTransition: string;
pageDesc?: string;
}
export type Props = StringTitleProp | ArrayTitleProp;
const { props } = Astro; const { props } = Astro;
+2 -2
View File
@@ -4,9 +4,9 @@ import PostDetails from "@/layouts/PostDetails.astro";
import getSortedPosts from "@/utils/getSortedPosts"; import getSortedPosts from "@/utils/getSortedPosts";
import { getPath } from "@/utils/getPath"; import { getPath } from "@/utils/getPath";
export interface Props { type Props = {
post: CollectionEntry<"blog">; post: CollectionEntry<"blog">;
} };
export async function getStaticPaths() { export async function getStaticPaths() {
const posts = await getCollection("blog", ({ data }) => !data.draft); const posts = await getCollection("blog", ({ data }) => !data.draft);