56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { X } from "lucide-react";
|
|
import {
|
|
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
|
|
MAP_READABLE_RADIUS_CLASS_NAME
|
|
} from "@/features/map/core/components/map-control-styles";
|
|
import { cn } from "@/lib/utils";
|
|
import type { DetailFeature } from "../types";
|
|
import { getLocalizedFeatureProperties } from "../utils/feature-properties";
|
|
|
|
type FeaturePopoverProps = {
|
|
feature: DetailFeature | null;
|
|
onClose: () => void;
|
|
};
|
|
|
|
export function FeaturePopover({ feature, onClose }: FeaturePopoverProps) {
|
|
if (!feature) {
|
|
return null;
|
|
}
|
|
|
|
const entries = getLocalizedFeatureProperties(feature.properties).slice(0, 4);
|
|
|
|
return (
|
|
<aside className={cn("pointer-events-auto absolute left-1/2 top-[92px] z-20 w-[min(360px,calc(100vw-32px))] -translate-x-1/2 border border-white/60 bg-white/70 p-4 shadow-2xl shadow-blue-950/20 backdrop-blur-2xl", MAP_MAJOR_PANEL_RADIUS_CLASS_NAME)}>
|
|
<div className="flex items-start justify-between gap-3">
|
|
<div className="min-w-0">
|
|
<p className="text-xs font-semibold text-blue-600">{feature.layer === "pipes" ? "管线要素" : "节点要素"}</p>
|
|
<h3 className="mt-1 truncate text-base font-semibold text-slate-950">{feature.title}</h3>
|
|
<p className="mt-1 truncate text-sm text-slate-500">{feature.subtitle}</p>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
aria-label="关闭要素信息"
|
|
title="关闭要素信息"
|
|
onClick={onClose}
|
|
className="grid h-8 w-8 shrink-0 place-items-center rounded-full text-slate-500 hover:bg-slate-100 hover:text-slate-900"
|
|
>
|
|
<X size={16} aria-hidden="true" />
|
|
</button>
|
|
</div>
|
|
|
|
{entries.length > 0 ? (
|
|
<dl className="mt-3 grid grid-cols-2 gap-2">
|
|
{entries.map((entry) => (
|
|
<div key={entry.key} className={cn("bg-white/95 px-3 py-2 shadow-lg shadow-blue-950/10", MAP_READABLE_RADIUS_CLASS_NAME)}>
|
|
<dt className="truncate text-xs font-medium text-slate-500">{entry.label}</dt>
|
|
<dd className="mt-1 truncate text-sm font-semibold text-slate-800">{entry.value}</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
) : null}
|
|
</aside>
|
|
);
|
|
}
|