Files
shanghai-residences/src/pages/chenyun/reflection/shared/ClueItem.tsx
T

87 lines
2.6 KiB
TypeScript

/**
* 线索项组件
* 可复用的线索展示组件,处理线索的点击、已浏览标记等
*/
import { Image } from "@/components";
import { cn, getStaticImage } from "@/lib/utils";
import type { ClueKey } from "./types";
export interface ClueItemProps {
/** 线索键名 */
clueKey: ClueKey;
/** 线索图片路径 */
imageSrc: string;
/** 是否已浏览 */
isViewed: boolean;
/** 点击回调 */
onClick: () => void;
/** 自定义类名 */
className?: string;
/** 已浏览标记的位置偏移 */
viewedMarkOffset?: { left?: string; top?: string; bottom?: string };
/** 已浏览标记文本,默认为"已浏览" */
viewedText?: string;
/** 线索类型:普通线索或电话线索 */
type?: "normal" | "phone";
}
/**
* 线索项组件
* 显示线索图片、搜索动画(未浏览时)、已浏览标记(已浏览时)
*/
export const ClueItem = ({
clueKey,
imageSrc,
isViewed,
onClick,
className,
viewedMarkOffset = {},
viewedText = "已浏览",
type = "normal",
}: ClueItemProps) => {
// 根据线索类型确定搜索图标的位置
const searchIconPosition =
type === "phone" ? "left-[45%] top-[45%]" : "left-1/2 top-[45%]";
return (
<div className={cn("cursor-pointer", className)} onClick={onClick}>
{/* 线索图片 */}
<Image src={getStaticImage(imageSrc)} />
{/* 搜索图标 - 未浏览时显示 */}
{!isViewed && (
<Image
className={cn(
"absolute pointer-events-none animate-search",
searchIconPosition,
"-translate-x-1/2 -translate-y-1/2"
)}
src={getStaticImage("chenyun/reflection/探索")}
/>
)}
{/* 已浏览标记 */}
{isViewed && (
<div
className="absolute left-1/2 -translate-x-1/2 bottom-0"
style={{
marginLeft: viewedMarkOffset.left || (clueKey === "yinyuan-clue1" || clueKey === "yinyuan-clue2" ? "20px" : clueKey === "mimian-intelligence" ? "4px" : clueKey === "mimian-distribution" ? "12px" : "0"),
bottom: viewedMarkOffset.bottom || (type === "phone" ? "0" : "0"),
}}
>
<span
className={cn([
"text-[#ae6400] text-3xl font-bold",
type === "phone" ? "" : "whitespace-nowrap",
"[text-shadow:_-4px_-4px_0_#ffffff,_4px_-4px_0_#ffffff,_-4px_4px_0_#ffffff,_4px_4px_0_#ffffff,_-5px_0_0_#ffffff,_5px_0_0_#ffffff,_0_-5px_0_#ffffff,_0_5px_0_#ffffff]",
])}
>
{viewedText}
</span>
</div>
)}
</div>
);
};