nextui/apps/docs/components/blog-post.tsx
WK 4e41f50fa2
v2.7.10 (#5381)
* fix(date-picker): error state (#5317)

* fix(date-range-picker): fixed the error state in preset

* Update giant-sloths-shop.md

* Removed if statement

* chore(date-picker): prettier

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>

* fix(theme): clear button in mobile (#5252)

* fix(toast): fixed close button hover position

* fix(input): fixed the clear button rendering on smaller devices

* Delete .changeset/soft-spoons-march.md

* Update input.ts

* Undo unrelated toast changes

* fix(toast): icons (#5246)

* feat(shared-icons): add loading icon

* fix(toast): icons

* chore(toast): revise types for icons

* chore(changeset): add changeset

* refactor: migrate eslint to v9 (#5267)

* refactor: migrate eslint to v9

* chore: lint

* chore: update eslint command

* chore: fix lint warnings

* chore: separate lint and lint:fix

* chore: exclude contentlayer generated code

* fix(scripts): add missing await

* fix(autocomplete): persist last selected item position (#5286)

* refactor(select): remove unnecessary code

* fix(autocomplete): persist last selected item position

* chore(changeset): add changeset

* chore(deps): bump framer-motion version (#5287)

* chore(deps): bump framer-motion version

* fix: typing issues

* chore(changeset): add changeset

---------

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

* chore(docs): supplement onAction & selectionBehavior (#5289)

* fix(autocomplete): ensure focused item matches selected item after filter, selection (#5290)

* fix(autocomplete): ensure focused item matches selected item after filter, selection

* chore: apply type and default value

* chore: add perpose coment in updated code

* test: add focuskey management testcode

* docs: add changeset

* docs: update changeset

* chore: remove comment

* fix: broken components in stories (#5291)

* chore(switch): remove xl size

* chore(docs): remove xl size

* chore(system-rsc): remove xl size

* chore(circular-progress): remove xl size

* chore: undo

* chore(deps): bump RA versions (#5310)

* chore(deps): ra version bump

* chore(changeset): add changeset

* fix(scripts): incorrect docs path

---------

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

* chore(docs): update meta data (#5311)

* docs(layout.tsx): added text-foreground (#5316)

* feat(tabs): add click handling for tab items in tests and implementation (#3917)

Co-authored-by: WK Wong <wingkwong.code@gmail.com>

* fix issues in tabs examples (#2405)

Co-authored-by: WK Wong <wingkwong.code@gmail.com>

* chore(docs): add missing onValueChange in CheckboxGroup (#5332)

* ci(changesets): version packages (#5323)

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

* chore(deps): bump RA versions (#5361)

* chore(deps): bump RA versions

* chore(deps): bump RA versions

* chore(deps): bump RA versions

* chore: changeset

* refactor(listbox): already extends in AriaListBoxProps

* chore(docs): remove herohack announcement (#5363)

* chore: remove herohack announcement

* Update carbon-ad.tsx

* chore(docs): fixed lint errors

* chore(docs): requested changes

* Update carbon-ad.tsx

* Update carbon-ad.tsx

* fix(theme): consistent faded styling for isInvalid in InputOtp and DateInput (#5349)

* fix(input-otp): remove bg and border styles from faded variant when isInvalid

* fix(date-input): remove bg styles from faded variant when isInvalid

* chore(changeset): add changeset

* chore: bump theme peerDependencies

* chore: bump theme peerDependencies

* fix: wrong version

* chore: extra line

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>

* fix(theme): helperWrapper padding (#5350)

* fix(number-input): decreased helperWrapper padding to maintain consistency

* Update beige-laws-heal.md

* chore(theme): change to p-1

* chore(deps): bump peerDependencies for theme pkg

* fix(number-input): incorrect versions

* chore(changeset): include number input

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>

* fix(autocomplete): onClear (#5365)

* fix(autocomplete): add onClear

* feat(autocomplete): add test case for onClear

* chore(changeset): add changeset

* fix(number-input): only allow number type (#5368)

* refactor(number-input): avoid non number type passing to number input

* chore(changeset): add changeset

* refactor: optimization (#5362)

* chore(deps): bump RA versions

* chore(deps): bump RA versions

* chore(deps): bump RA versions

* chore: changeset

* chore(deps): remove unnecessary dependencies

* fix(calendar): typing issue

* refactor(system): remove unused SupportedCalendars

* refactor(system): move I18nProviderProps to type

* refactor: use `spectrumCalendarProps<DateValue>["createCalendar"]`

* feat: add consistent-type-imports

* fix: eslint

* chore: add changeset

* refactor: remove unused deps

* ci(changesets): version packages (#5364)

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

---------

Co-authored-by: Vishv Salvi <82429084+Vishvsalvi@users.noreply.github.com>
Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
Co-authored-by: KumJungMin <37934668+KumJungMin@users.noreply.github.com>
Co-authored-by: liaoyinglong <vigossliao@gmail.com>
Co-authored-by: zhengjitf <zhengjitf@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Anuj Kuralkar <76731106+anuj-kuralkar@users.noreply.github.com>
2025-06-16 11:28:11 -03:00

84 lines
2.6 KiB
TypeScript

"use client";
import type {BlogPost} from "contentlayer2/generated";
import {Card, CardFooter, CardBody, CardHeader, Link, Avatar, Image} from "@heroui/react";
import Balancer from "react-wrap-balancer";
import {format, parseISO} from "date-fns";
import NextLink from "next/link";
import {AnimatePresence, motion} from "framer-motion";
import {usePostHog} from "posthog-js/react";
import {useIsMounted} from "@/hooks/use-is-mounted";
const BlogPostCard = (post: BlogPost) => {
const isMounted = useIsMounted();
const posthog = usePostHog();
const handlePress = () => {
posthog.capture("BlogPostCard - Selection", {
name: post.title,
action: "click",
category: "blog",
data: post.url ?? "",
});
};
return (
<AnimatePresence>
{isMounted && (
<motion.article
animate={{opacity: 1, y: 0}}
exit={{opacity: 0, y: 5}}
initial={{opacity: 0, y: 5}}
transition={{duration: 0.3}}
>
<Card
disableRipple
isBlurred
as={NextLink}
className="p-2 h-full border-transparent text-start bg-white/5 dark:bg-default-400/10 backdrop-blur-lg backdrop-saturate-[1.8]"
href={post.url}
isPressable={!!post.url}
onPress={handlePress}
>
<CardHeader>
<Link
as={NextLink}
className="font-semibold text-foreground"
href={post.url}
size="lg"
underline="hover"
onPress={handlePress}
>
<Balancer>{post.title}</Balancer>
</Link>
</CardHeader>
<CardBody className="pt-0 px-2 pb-1">
<Image className="mb-4" src={post.image} />
<p className="font-normal w-full text-default-600">{post.description}</p>
</CardBody>
<CardFooter className="flex justify-between items-center">
<time className="block text-small text-default-500" dateTime={post.date}>
{format(parseISO(post.date), "LLLL d, yyyy")} {post?.draft && " (Draft)"}
</time>
<Avatar size="sm" src={post.author?.avatar} />
</CardFooter>
</Card>
</motion.article>
)}
</AnimatePresence>
);
};
export const BlogPostList = ({posts}: {posts: BlogPost[]}) => {
return (
<div className="mt-10 grid gap-4 grid-cols-[repeat(auto-fill,minmax(300px,1fr))]">
{posts.map((post, idx) => (
<BlogPostCard key={idx} {...post} />
))}
</div>
);
};