feat(charts): manage investigation charts in a scrolling workspace
Generic Container CI/CD / test-build-publish (push) Successful in 2m7s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 2m8s

This commit is contained in:
2026-11-10 17:56:23 +08:00
parent 865491cb23
commit 0ae0a41e61
80 changed files with 4672 additions and 470 deletions
@@ -2,6 +2,7 @@ import type { LucideIcon } from "lucide-react";
import type { ReactNode } from "react";
import { cn } from "@/shared/ui/cn";
import {
mapOptionInteractionVariants,
MAP_COMPACT_RADIUS_CLASS_NAME,
MAP_ICON_CELL_RADIUS_CLASS_NAME,
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
@@ -79,14 +80,15 @@ export function MapModeButton({ icon: Icon, label, active = false, disabled = fa
return (
<button
type="button"
data-map-option=""
aria-pressed={active}
disabled={disabled}
onClick={onClick}
className={cn(
"flex h-14 flex-col items-center justify-center gap-1 text-xs font-semibold transition duration-150",
"flex h-14 flex-col items-center justify-center gap-1 border border-transparent text-xs font-semibold",
MAP_COMPACT_RADIUS_CLASS_NAME,
active ? "bg-[var(--action-blue)] text-white" : "surface-control text-slate-600 hover:text-[var(--action-blue-hover)]",
disabled && "cursor-not-allowed opacity-55 hover:text-slate-600"
active ? "bg-[var(--action-blue)] text-white" : "surface-control text-slate-600",
mapOptionInteractionVariants({ state: active ? "selected" : "default" })
)}
>
<Icon size={17} aria-hidden="true" />
@@ -109,13 +111,14 @@ export function MapActionChip({
return (
<button
type="button"
data-map-option=""
disabled={disabled}
onClick={onClick}
className={cn(
"flex h-10 items-center justify-center gap-1.5 text-xs font-semibold text-slate-700 transition duration-150 hover:border-[var(--surface-border)] hover:text-[var(--action-blue-hover)]",
"flex h-10 items-center justify-center gap-1.5 text-xs font-semibold text-slate-700",
MAP_COMPACT_RADIUS_CLASS_NAME,
MAP_READABLE_SURFACE_CLASS_NAME,
disabled && "cursor-not-allowed opacity-55 hover:border-white/70 hover:text-slate-700"
mapOptionInteractionVariants()
)}
>
<Icon size={14} aria-hidden="true" />
@@ -157,23 +160,20 @@ export function MapActionRow({
return (
<button
type="button"
data-map-option=""
disabled={disabled}
onClick={onClick}
className={cn(
"flex min-h-12 w-full items-center gap-2.5 border px-2.5 py-2 text-left",
MAP_COMPACT_RADIUS_CLASS_NAME,
isPrimary
? "border-[var(--action-blue)] bg-[var(--action-blue)] text-white shadow-lg shadow-[color:var(--action-blue)]/25 hover:bg-[var(--action-blue-hover)]"
? "border-[var(--action-blue)] bg-[var(--action-blue)] text-white shadow-lg shadow-[color:var(--action-blue)]/25"
: strong
? "border-[var(--surface-border)] bg-[var(--action-soft)]/95 text-[var(--action-blue-pressed)]"
: "surface-control border-transparent text-slate-700 hover:border-[var(--surface-border)] hover:bg-[var(--surface-reading)] hover:text-[var(--action-blue-hover)]",
isDanger && "hover:border-red-100 hover:text-red-700",
: "surface-control border-transparent text-slate-700",
selected && !isPrimary && "border-[var(--surface-border)] bg-[var(--action-soft)] text-[var(--action-blue-pressed)]",
mapOptionInteractionVariants({ state: isDanger ? "danger" : isPrimary ? "primary" : selected || strong ? "selected" : "default" }),
muted && "opacity-70",
disabled &&
(isPrimary
? "cursor-not-allowed opacity-55 hover:border-[var(--action-blue)] hover:bg-[var(--action-blue-hover)] hover:text-white"
: "cursor-not-allowed opacity-55 hover:border-white/70 hover:bg-[var(--surface-reading)]/95 hover:text-slate-700"),
disabled && "shadow-none"
)}
>
@@ -185,8 +185,8 @@ export function MapActionRow({
? "bg-[var(--surface-reading)]/16 text-white"
: selected || strong
? "bg-[var(--action-blue)] text-white"
: "bg-[var(--surface-control)] text-[var(--ink-muted)]",
isDanger && "bg-red-50 text-red-600"
: "bg-[var(--surface-control)] text-inherit",
isDanger && "bg-[var(--status-danger-soft)] text-[var(--status-danger-foreground)]"
)}
>
<Icon size={15} aria-hidden="true" />