1import type { ReactNode } from "react";
2import type { LucideIcon } from "lucide-react";
3
4import { cn } from "~/lib/utils";
5import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip";
6
7export function TimelineSystemDivider(props: {
8 readonly label: string;
9 readonly detail?: ReactNode | null;
10 readonly tone?: "neutral" | "danger";
11 readonly icon?: LucideIcon;
12 readonly showDetailSeparator?: boolean;
13 readonly actionLabel?: string;
14 readonly onAction?: () => void;
15}) {
16 const Icon = props.icon;
17 const content = (
18 <>
19 {Icon ? <Icon className="size-3 shrink-0" /> : null}
20 <span className="font-medium">{props.label}</span>
21 {props.detail ? (
22 <span
23 className={cn(
24 "inline-flex min-w-0 items-center opacity-70",
25 typeof props.detail === "string" && "max-w-80 truncate",
26 )}
27 >
28 {props.showDetailSeparator === false ? null : "·\u00a0"}
29 {props.detail}
30 </span>
31 ) : null}
32 </>
33 );
34
35 return (
36 <div
37 className={cn(
38 "flex min-w-0 items-center gap-2 py-2 text-2xs text-muted-foreground",
39 props.tone === "danger" && "text-destructive",
40 )}
41 >
42 <span aria-hidden="true" className="h-px flex-1 bg-border/70" />
43 {props.onAction ? (
44 <Tooltip>
45 <TooltipTrigger
46 render={
47 <button
48 type="button"
49 aria-label={props.actionLabel}
50 onClick={props.onAction}
51 className="flex min-w-0 cursor-pointer items-center gap-1.5 rounded-full border border-border/70 bg-background px-2.5 py-1 transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/70"
52 />
53 }
54 >
55 {content}
56 </TooltipTrigger>
57 <TooltipPopup side="top">{props.actionLabel}</TooltipPopup>
58 </Tooltip>
59 ) : (
60 <span className="flex min-w-0 flex-wrap items-center justify-center gap-1.5 rounded-full px-2 py-1">
61 {content}
62 </span>
63 )}
64 <span aria-hidden="true" className="h-px flex-1 bg-border/70" />
65 </div>
66 );
67}