Feat: Add LightBox Component

新增 LightBox 组件用于展示媒体,优化了 Tailwind CSS 配置,增加了动画效果,并在响应式设计中调整了字体大小和样式。
This commit is contained in:
2025-08-16 15:32:13 +08:00
parent 52bea590eb
commit 0a9ae15732
7 changed files with 309 additions and 17 deletions
+16 -3
View File
@@ -3,6 +3,7 @@ import { json, LoaderFunctionArgs, type MetaFunction } from "@remix-run/node";
import Pagination from "~/components/common/pagination";
import { clsn, siteTitle } from "~/utils";
import { StarFill } from "~/components/common/icons";
import LightBox, { useLightBox } from "~/components/biz/gallery/image-box";
import styles from "./styles.module.less";
@@ -43,6 +44,9 @@ export default function Gallery() {
const navigate = useNavigate();
const { media, category, page } = useLoaderData<typeof loader>();
// const lightBoxInst = useRef();
const { ref: lightBoxInst, open } = useLightBox();
const onChangePage = (value: number) => {
navigate({
search: `?page=${value}`,
@@ -65,11 +69,18 @@ export default function Gallery() {
</div>
</section>
<section className="grid gap-4 lg:gap-8 grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 mb-12">
{media.data.map((item) => (
<div key={item.id} className="relative bg-white rounded-xl overflow-hidden border-4 border-transparent hover:border-pink-400 transition-colors border-b-4 border-b-cyan-200">
{media.data.map((item, index) => (
<div
key={item.id}
role="button"
tabIndex={0}
onKeyDown={() => {}}
className="relative bg-white rounded-xl overflow-hidden border-4 border-transparent hover:border-pink-400 transition-colors border-b-4 border-b-cyan-200 group"
onClick={() => open(index)}
>
<img className={styles.image} src={item.thumb_url} alt={item.title} loading="lazy" />
{item.content && (
<div className={clsn("absolute top-0 left-0 right-0 bottom-0 bg-opacity-60 bg-black p-4 sm:p-6 text-white leading-7 transition-opacity duration-300 opacity-0 hover:opacity-100", styles.desc)}>
<div className={clsn("absolute top-0 left-0 right-0 bottom-0 bg-opacity-60 bg-black p-4 sm:p-6 text-white leading-7 transition-opacity duration-300 whitespace-pre-wrap opacity-0 group-hover:opacity-100", styles.desc)}>
{item.content}
</div>
)}
@@ -88,6 +99,8 @@ export default function Gallery() {
<section className="text-center">
<Pagination current={Number(page)} size={20} total={media.count} onClick={onChangePage} />
</section>
<LightBox ref={lightBoxInst} list={media.data} />
</main>
);
}
+4 -4
View File
@@ -67,11 +67,11 @@ export default function Note() {
{item.starred && (
<StarFill className="absolute -top-5 -right-5 w-28 h-28 text-yellow-300 text-opacity-20 -rotate-[23deg]" />
)}
<h2 className={clsn(cover && "mr-40", "text-pink-400 text-2xl font-bold mb-4")} style={{ viewTransitionName: `note-title-${item.id}` }}>
<h2 className={clsn(cover && "md:mr-40", "text-pink-400 text-2xl font-bold mb-4")} style={{ viewTransitionName: `note-title-${item.id}` }}>
{item.title}
</h2>
<p className={clsn(cover && "mr-40", "mb-8 relative")}>{item.except}</p>
<div className={clsn(cover && "mr-40", "flex items-end justify-between text-sm")}>
<p className={clsn(cover && "sm:mr-40", "mb-8 relative")}>{item.except}</p>
<div className={clsn(cover && "mb-40 sm:mb-0 sm:mr-40", "flex items-end justify-between text-sm")}>
<p className="opacity-60">{item.date}</p>
<span className="flex items-center opacity-60">
<ThumbUpFill className="h-4 w-4 mr-1" />
@@ -80,7 +80,7 @@ export default function Note() {
</div>
{cover && (
<div
className="absolute top-0 right-0 bottom-0 w-40 transition-opacity bg-cover opacity-30 group-hover:opacity-80"
className="absolute h-40 sm:h-auto sm:w-40 left-0 sm:top-0 sm:left-[unset] right-0 bottom-0 transition-opacity bg-cover opacity-30 group-hover:opacity-80"
style={{ backgroundImage: `url("${cover}")`, clipPath: "polygon(25% 0%, 100% 0%, 100% 100%, 0% 100%)" }}
/>
)}