55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import { Component } from 'solid-js';
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import BaseCarousel from "@/components/ui/base-carousel";
|
|
import { HomeLink } from '@/types/home';
|
|
|
|
interface HomeCarouselProps {
|
|
slides?: HomeLink[];
|
|
loading?: boolean;
|
|
class?: string;
|
|
}
|
|
|
|
const HomeCarousel: Component<HomeCarouselProps> = (props) => {
|
|
const renderItem = (slide: NonNullable<HomeCarouselProps['slides']>[number]) => (
|
|
<a
|
|
href={slide.linkUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="text-center w-full h-[120px] relative bg-cover bg-center bg-no-repeat block"
|
|
style={{"background-image": `url(${slide.imgUrl})`}}
|
|
>
|
|
{/* 添加一个半透明的遮罩层使文字更易读 */}
|
|
<div class="absolute inset-0 bg-black/50" />
|
|
<div class="relative z-10 p-4 flex flex-col justify-center h-full">
|
|
<h3 class="text-xl font-semibold mb-2 break-words text-white">{slide.name}</h3>
|
|
<p class="text-sm text-gray-200 break-words">{slide.more}</p>
|
|
</div>
|
|
</a>
|
|
);
|
|
|
|
const renderSkeleton = () => (
|
|
<div class="text-center w-full h-full relative">
|
|
<div class="absolute inset-0">
|
|
<Skeleton class="w-full h-full" />
|
|
</div>
|
|
<div class="relative z-10 p-4 flex flex-col justify-center h-full">
|
|
<div class="mb-2">
|
|
<Skeleton height={24} width={60} class="mx-auto" />
|
|
</div>
|
|
<Skeleton height={16} width={80} class="mx-auto" />
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<BaseCarousel
|
|
class={props.class}
|
|
items={props.slides}
|
|
loading={props.loading}
|
|
renderItem={renderItem}
|
|
renderSkeleton={renderSkeleton}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default HomeCarousel; |