import { useState } from "react";
import type { Hotspot, HotspotAction } from "../types/annotations";
interface HotspotEditorProps {
hotspots: Hotspot[];
selectedHotspotId: string | null;
placingMode: boolean;
currentFrame: number;
totalFrames: number;
onSelectHotspot: (id: string) => void;
onDeleteHotspot: (id: string) => void;
onTogglePlacingMode: () => void;
onUpdateHotspot: (id: string, updater: (hotspot: Hotspot) => Hotspot) => void;
}
const buildDefaultAction = (type: HotspotAction["type"]): HotspotAction => {
if (type === "tooltip") return { type: "tooltip", text: "" };
if (type === "seek") return { type: "seek", targetFrame: 0 };
return { type: "url", href: "", newTab: true };
};
// Linear-style numeric stepper
const Stepper = ({
value,
onChange,
min = 0,
max = 100,
suffix = "",
}: {
value: number;
onChange: (v: number) => void;
min?: number;
max?: number;
suffix?: string;
}) => (
{/* Back header */}
{/* Action type */}
{(["tooltip", "url", "seek"] as const).map((type) => (
))}
{/* Style */}
{(
[
{ style: "pulse" as const, label: "Hotspot" },
{ style: "circle" as const, label: "Pin" },
{ style: "rectangle" as const, label: "Area" },
] as const
).map(({ style, label }) => (
))}
{/* Action content - Linear style */}
{selectedHotspot.action.type === "tooltip" && (
)}
{selectedHotspot.action.type === "url" && (
onUpdateHotspot(selectedHotspot.id, (c) => ({
...c,
action: { ...c.action, href: e.target.value },
}))
}
placeholder="https://..."
style={{
width: "100%",
padding: "10px 12px",
borderRadius: "var(--radius-md)",
border: "1px solid var(--border-default)",
background: "var(--bg-elevated)",
color: "var(--text-primary)",
fontSize: "13px",
fontFamily: "var(--font-mono)",
outline: "none",
marginBottom: "10px",
transition: "border-color 150ms",
}}
onFocus={(e) => {
e.currentTarget.style.borderColor = "var(--accent-1)";
}}
onBlur={(e) => {
e.currentTarget.style.borderColor = "var(--border-default)";
}}
/>
)}
{selectedHotspot.action.type === "seek" && (
onUpdateHotspot(selectedHotspot.id, (c) => ({
...c,
action: { type: "seek", targetFrame: v },
}))
}
max={totalFrames}
/>
)}
{/* Timing - Linear style */}
update("frameStart", v)}
max={totalFrames}
/>
update("frameEnd", v)}
max={totalFrames}
/>
{/* Advanced toggle - Linear style */}
{showAdvanced && (
update("x", v)}
suffix="%"
/>
update("y", v)}
suffix="%"
/>
update("width", v)}
suffix="%"
/>
update("height", v)}
suffix="%"
/>
)}
{/* Delete - Linear style */}
);
}
export default HotspotEditor;